# https://docs.pyrevitlabs.io/ llms-full.txt ## pyRevit Development Tools [Skip to content](https://docs.pyrevitlabs.io/#pyrevit-can-help-you) pyRevitRapid Application Development (RAD)Environment for Autodesk Revit® [![GitHub issues](https://img.shields.io/github/issues/pyrevitlabs/pyRevit.svg?style=for-the-badge)](https://github.com/pyrevitlabs/pyRevit/issues)[![GitHub forks](https://img.shields.io/github/forks/pyrevitlabs/pyRevit.svg?style=for-the-badge)](https://github.com/pyrevitlabs/pyRevit/network)[![GitHub stars](https://img.shields.io/github/stars/pyrevitlabs/pyRevit.svg?style=for-the-badge&colorB=red)](https://github.com/pyrevitlabs/pyRevit/stargazers)[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg?style=for-the-badge)](http://www.gnu.org/licenses/gpl-3.0)[![made with love in portland](https://img.shields.io/badge/%3C%2F%3E%20with%20%3C3-Portland%2C%20OR-green.svg?style=for-the-badge)](https://en.wikipedia.org/wiki/Portland,_Oregon) pyRevit helps you quickly sketch out your automation and addon ideas, in whichever language that you are most comfortable with, inside the Revit environment and using its APIs. It also ships with an extensive set of powerful tools that showcase its capabilities as a development environment. Download and install pyRevit, launch Revit, and note the new pyRevit tab that includes these tools. pyRevit also ships with a handy CLI utility for customized configuration and deployment of your tools, and a telemetry server to monitor pyRevit usage across your teams. ### pyRevit can help you - Add a **powerful set of free tools to your Revit workflows**. - **Sketch out** your automation **ideas quickly** in python - **Write your own Revit addons** for Revit using python ( [IronPython](https://ironpython.net/) or [CPython](https://www.python.org/)), C#, VB.Net - **Distribute your tools** (pyRevit, [Dynamo](https://dynamobim.org/), or [Grasshopper](https://www.rhino3d.com/inside)) easily to your teams using a unified interface - **Share your tools** with the community # Getting Started ## Get Started Using pyRevit [Install pyRevit](https://www.notion.so/Install-pyRevit-98ca4359920a42c3af5c12a7c99a196d) [Create Custom Patterns](https://www.notion.so/Create-Custom-Patterns-6b8db11b87ed49d98144b75407685152) [Manage Keynotes](https://www.notion.so/Manage-Keynotes-6f083d6f66fe43d68dc5d5407c8e19da) [Configure pyRevit](https://www.notion.so/Configure-pyRevit-461d8f564ba743d0ad7e843a7b3b2afe) [Install Extensions](https://www.notion.so/Install-Extensions-0753ab78c0ce46149f962acc50892491) **↓** More guides are available here [HOW TO Guides](https://www.notion.so/HOW-TO-Guides-dc20e0e227b74d9bbc775699904152cb) ## Get Started Developing for pyRevit [Create Your First Command](https://www.notion.so/Create-Your-First-Command-2509b43e28bd498fba937f5c1be7f485) **↓** Read the pyRevit API reference to know everything about pyRevit available modules, functions, ... [pyRevit API Reference](https://pyrevitlabs.github.io/pyRevit/reference/pyrevit/) **↓** Read the docs to know everything about pyRevit scripts, extensions, ... [Developer Docs](https://www.notion.so/Developer-Docs-2c88f3ecccde422d9504e20b6b9e04f8) **↓** pyRevit has a powerful command line utility [pyRevit CLI](https://www.notion.so/pyRevit-CLI-c50de95259114db795db5bd3f19f8e2a) **↓** And when you are ready to deploy your tools to your team [pyRevit For Teams](https://www.notion.so/pyRevit-For-Teams-ddc6c312d6f6488691eed2ec7704fd97) # Staying Updated Follow [pyRevit on Twitter](https://twitter.com/pyrevit) to stay notified about the upcoming changes and follow [pyRevit Release Notes](https://github.com/pyrevitlabs/pyRevit/releases) for the breaking changes **↓** Check out the blog for news [Blog](https://www.notion.so/Blog-5bcadb69d8ab43c8ba5ee547e42a129f) **↓** And the future plans for pyRevit are laid out here [Roadmap](https://www.notion.so/Roadmap-8f353f66ffe94a5ea6676f0d3c5df5bd) # Dealing with Issues Check the list of [Currently Open](https://github.com/pyrevitlabs/pyRevit/issues) and [Previously Reported Issues](https://github.com/pyrevitlabs/pyRevit/issues?q=is%3Aissue+is%3Aclosed) for anything similar to yours. **↓** See the FAQ page for questions [FAQs](https://www.notion.so/FAQs-70774c29e0ed41388f9a7857bc2e24dc) **↓** See the guide below on how to report new issues [Reporting New Issues](https://www.notion.so/Reporting-New-Issues-f1fdd62cf6074b318bfe8ddfbc2d8d98) # Getting Involved **↓** Get involved with the community of developers, creating tools with and for pyRevit [Community](https://www.notion.so/Community-eb501192c78c4d2f884f0cc34532058e) ## Share Your Passion **↓** Help making pyRevit better [Help with Documentation](https://www.notion.so/Help-with-Documentation-3ad04b6431a046a3bc9ca584eeea51fa) [Help Translate pyRevit](https://www.notion.so/Help-Translate-pyRevit-c26063a6c9824667a07c6a40b28c70d4) [Create Tutorials](https://www.notion.so/Create-Tutorials-d25685ddb11d4eb6a76001325715cfb5) [Share Revit Build Numbers](https://www.notion.so/Share-Revit-Build-Numbers-90817d95875c48d0accb802035bfcb68) ## Share Your Code **↓** Help making pyRevit core and tools better [Improve pyRevit Core](https://www.notion.so/Improve-pyRevit-Core-109f014ece0043ed8e523605312b1305) [Contribute New Tools](https://www.notion.so/Contribute-New-Tools-800ecc0cee8e47b484f22359c4fe4307) [Share Your Extensions](https://www.notion.so/Share-Your-Extensions-48ff84d4eae846f4aa9567fca32ff4fe) [Bundle Shelf](https://www.notion.so/Bundle-Shelf-d1b57b18fd33426aa77d29de2e8b6cf7) ## Share Your Coins **↓** Help making pyRevit financially stronger [Support on OpenCollective](https://opencollective.com/pyrevitlabs) [Support Guidelines](https://www.notion.so/Support-on-Patreon-cdf92ba547154f7a85d32b526dc5e59b) [Supporters](https://www.notion.so/Supporters-4f3350243ba24dcd8228df6262723629) # Contributors Made with [contrib.rocks](https://contrib.rocks/) [![](https://contrib.rocks/image?repo=pyrevitlabs/pyRevit)](https://github.com/pyrevitlabs/pyRevit/graphs/contributors) * * * \\*\\*\\*\\* with 🖤 in [Portland](https://en.m.wikipedia.org/wiki/Portland,_Oregon), Oregon Copyright © 2014-2025 by Ehsan Iran-Nejad (pyrevitlabs.io) - All Rights Reserved No part of this publication may be reproduced, distributed, or transmitted in any form or by any means, including photocopying, recording, or other electronic or mechanical methods, without the prior written permission of the publisher. Back to top ## pyRevit Output Window [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/output/#pyrevit.output) # output Provide access to output window and its functionality. This module provides access to the output window for the currently running pyRevit command. The proper way to access this wrapper object is through the :func: `get_output` of :mod: `pyrevit.script` module. This method, in return uses the `pyrevit.output` module to get access to the output wrapper. Examples: ```md-code__content from pyrevit import script output = script.get_output() ``` Here is the source of :func: `pyrevit.script.get_output`. As you can see this functions calls the :func: `pyrevit.output.get_output` to receive the output wrapper. .. literalinclude:: ../../pyrevitlib/pyrevit/script.py :pyobject: get\_output ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `DEFAULT_STYLESHEET_NAME = 'outputstyles.css'``module-attribute` ### `active_stylesheet = user_config.output_stylesheet or get_default_stylesheet()``module-attribute` ## Classes ### `PyRevitOutputWindow` Bases: `object` Wrapper to interact with the output window. #### Attributes ##### `window``property` `PyRevitLabs.PyRevit.Runtime.ScriptConsole`: Return output window object. ##### `renderer``property` Return html renderer inside output window. Returns: | Type | Description | | --- | --- | | `WebBrowser` | HTML renderer | ##### `output_id``property` str: Return id of the output window. In current implementation, Id of output window is equal to the unique id of the pyRevit command it belongs to. This means that all output windows belonging to the same pyRevit command, will have identical output\_id values. ##### `output_uniqueid``property` str: Return unique id of the output window. In current implementation, unique id of output window is a GUID string generated when the output window is opened. This id is unique to the instance of output window. ##### `is_closed_by_user``property` Whether the window has been closed by the user. ##### `last_line``property` Last line of the output window. ##### `debug_mode``property``writable` Set debug mode on output window and stream. This will cause the output window to print information about the buffer stream and other aspects of the output window mechanism. #### Functions ##### `self_destruct(seconds)` Set self-destruct (close window) timer. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `seconds` | `int` | number of seconds after which window is closed. | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
163
164
165
166
167
168
169
170
``` | ```md-code__content
def self_destruct(self, seconds):
"""Set self-destruct (close window) timer.
Args:
seconds (int): number of seconds after which window is closed.
"""
if self.window:
self.window.SelfDestructTimer(seconds)
``` | ##### `inject_to_head(element_tag, element_contents, attribs=None)` Inject html element to current html head of the output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_tag` | `str` | html tag of the element e.g. 'div' | _required_ | | `element_contents` | `str` | html code of the element contents | _required_ | | `attribs` | | obj: `dict`): dictionary of attribute names and value | `None` | Examples: ```md-code__content output = pyrevit.output.get_output() output.inject_to_head('script', '', # no script since it's a link {'src': js_script_file_path}) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
``` | ````md-code__content
def inject_to_head(self, element_tag, element_contents, attribs=None):
"""Inject html element to current html head of the output window.
Args:
element_tag (str): html tag of the element e.g. 'div'
element_contents (str): html code of the element contents
attribs (:obj:`dict`): dictionary of attribute names and value
Examples:
```python
output = pyrevit.output.get_output()
output.inject_to_head('script',
'', # no script since it's a link
{'src': js_script_file_path})
```
"""
html_element = self.renderer.Document.CreateElement(element_tag)
if element_contents:
html_element.InnerHtml = element_contents
if attribs:
for attribute, value in attribs.items():
html_element.SetAttribute(attribute, value)
# inject the script into head
head_el = self._get_head_element()
head_el.AppendChild(html_element)
if self.window:
self.window.WaitReadyBrowser()
```` | ##### `inject_to_body(element_tag, element_contents, attribs=None)` Inject html element to current html body of the output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_tag` | `str` | html tag of the element e.g. 'div' | _required_ | | `element_contents` | `str` | html code of the element contents | _required_ | | `attribs` | | obj: `dict`): dictionary of attribute names and value | `None` | Examples: ```md-code__content output = pyrevit.output.get_output() output.inject_to_body('script', '', # no script since it's a link {'src': js_script_file_path}) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
``` | ````md-code__content
def inject_to_body(self, element_tag, element_contents, attribs=None):
"""Inject html element to current html body of the output window.
Args:
element_tag (str): html tag of the element e.g. 'div'
element_contents (str): html code of the element contents
attribs (:obj:`dict`): dictionary of attribute names and value
Examples:
```python
output = pyrevit.output.get_output()
output.inject_to_body('script',
'', # no script since it's a link
{'src': js_script_file_path})
```
"""
html_element = self.renderer.Document.CreateElement(element_tag)
if element_contents:
html_element.InnerHtml = element_contents
if attribs:
for attribute, value in attribs.items():
html_element.SetAttribute(attribute, value)
# inject the script into body
body_el = self._get_body_element()
body_el.AppendChild(html_element)
if self.window:
self.window.WaitReadyBrowser()
```` | ##### `inject_script(script_code, attribs=None, body=False)` Inject script tag into current head (or body) of the output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `script_code` | `str` | javascript code | _required_ | | `attribs` | | obj: `dict`): dictionary of attribute names and value | `None` | | `body` | `bool` | injects script into body instead of head | `False` | Examples: ```md-code__content output = pyrevit.output.get_output() output.inject_script('', # no script since it's a link {'src': js_script_file_path}) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
``` | ````md-code__content
def inject_script(self, script_code, attribs=None, body=False):
"""Inject script tag into current head (or body) of the output window.
Args:
script_code (str): javascript code
attribs (:obj:`dict`): dictionary of attribute names and value
body (bool, optional): injects script into body instead of head
Examples:
```python
output = pyrevit.output.get_output()
output.inject_script('', # no script since it's a link
{'src': js_script_file_path})
```
"""
if body:
self.inject_to_body('script', script_code, attribs=attribs)
else:
self.inject_to_head('script', script_code, attribs=attribs)
```` | ##### `add_style(style_code, attribs=None)` Inject style tag into current html head of the output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `style_code` | `str` | css styling code | _required_ | | `attribs` | | obj: `dict`): dictionary of attribute names and value | `None` | Examples: ```md-code__content output = pyrevit.output.get_output() output.add_style('body { color: blue; }') ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
252
253
254
255
256
257
258
259
260
261
262
263
264
265
``` | ````md-code__content
def add_style(self, style_code, attribs=None):
"""Inject style tag into current html head of the output window.
Args:
style_code (str): css styling code
attribs (:obj:`dict`): dictionary of attribute names and value
Examples:
```python
output = pyrevit.output.get_output()
output.add_style('body { color: blue; }')
```
"""
self.inject_to_head('style', style_code, attribs=attribs)
```` | ##### `get_head_html()` str: Return inner code of html head element. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
267
268
269
``` | ```md-code__content
def get_head_html(self):
"""str: Return inner code of html head element."""
return self._get_head_element().InnerHtml
``` | ##### `set_title(new_title)` Set window title to the new title. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
271
272
273
274
``` | ```md-code__content
def set_title(self, new_title):
"""Set window title to the new title."""
if self.window:
self.window.Title = new_title
``` | ##### `set_width(width)` Set window width to the new width. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def set_width(self, width):
"""Set window width to the new width."""
if self.window:
self.window.Width = width
``` | ##### `set_height(height)` Set window height to the new height. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def set_height(self, height):
"""Set window height to the new height."""
if self.window:
self.window.Height = height
``` | ##### `set_font(font_family, font_size)` Set window font family to the new font family and size. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `font_family` | `str` | font family name e.g. 'Courier New' | _required_ | | `font_size` | `int` | font size e.g. 16 | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
286
287
288
289
290
291
292
293
294
295
296
297
``` | ```md-code__content
def set_font(self, font_family, font_size):
"""Set window font family to the new font family and size.
Args:
font_family (str): font family name e.g. 'Courier New'
font_size (int): font size e.g. 16
"""
self.renderer.Font = \
framework.Drawing.Font(font_family,
font_size,
framework.Drawing.FontStyle.Regular,
framework.Drawing.GraphicsUnit.Point)
``` | ##### `resize(width, height)` Resize window to the new width and height. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
299
300
301
302
``` | ```md-code__content
def resize(self, width, height):
"""Resize window to the new width and height."""
self.set_width(width)
self.set_height(height)
``` | ##### `center()` Center the output window on the screen. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
304
305
306
307
308
309
310
311
312
313
314
``` | ```md-code__content
def center(self):
"""Center the output window on the screen."""
screen_area = HOST_APP.proc_screen_workarea
left = \
(abs(screen_area.Right - screen_area.Left) / 2) \
- (self.get_width() / 2)
top = \
(abs(screen_area.Top - screen_area.Bottom) / 2) \
- (self.get_height() / 2)
self.window.Left = left
self.window.Top = top
``` | ##### `get_title()` str: Return current window title. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
316
317
318
319
``` | ```md-code__content
def get_title(self):
"""str: Return current window title."""
if self.window:
return self.window.Text
``` | ##### `get_width()` int: Return current window width. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
321
322
323
324
``` | ```md-code__content
def get_width(self):
"""int: Return current window width."""
if self.window:
return self.window.Width
``` | ##### `get_height()` int: Return current window height. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
326
327
328
329
``` | ```md-code__content
def get_height(self):
"""int: Return current window height."""
if self.window:
return self.window.Height
``` | ##### `close()` Close the window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
331
332
333
334
``` | ```md-code__content
def close(self):
"""Close the window."""
if self.window:
self.window.Close()
``` | ##### `close_others(all_open_outputs=False)` Close all other windows that belong to the current command. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `all_open_outputs` | `bool` | Close all any other windows if True | `False` | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
336
337
338
339
340
341
342
343
344
345
346
``` | ```md-code__content
def close_others(self, all_open_outputs=False):
"""Close all other windows that belong to the current command.
Args:
all_open_outputs (bool): Close all any other windows if True
"""
if all_open_outputs:
ScriptConsoleManager.CloseActiveOutputWindows(self.window)
else:
ScriptConsoleManager.CloseActiveOutputWindows(self.window,
self.output_id)
``` | ##### `hide()` Hide the window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
348
349
350
351
``` | ```md-code__content
def hide(self):
"""Hide the window."""
if self.window:
self.window.Hide()
``` | ##### `show()` Show the window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
353
354
355
356
``` | ```md-code__content
def show(self):
"""Show the window."""
if self.window:
self.window.Show()
``` | ##### `lock_size()` Lock window size. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
358
359
360
361
``` | ```md-code__content
def lock_size(self):
"""Lock window size."""
if self.window:
self.window.LockSize()
``` | ##### `unlock_size()` Unock window size. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
363
364
365
366
``` | ```md-code__content
def unlock_size(self):
"""Unock window size."""
if self.window:
self.window.UnlockSize()
``` | ##### `freeze()` Freeze output content update. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
368
369
370
371
``` | ```md-code__content
def freeze(self):
"""Freeze output content update."""
if self.window:
self.window.Freeze()
``` | ##### `unfreeze()` Unfreeze output content update. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
373
374
375
376
``` | ```md-code__content
def unfreeze(self):
"""Unfreeze output content update."""
if self.window:
self.window.Unfreeze()
``` | ##### `save_contents(dest_file)` Save html code of the window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dest_file` | `str` | full path of the destination html file | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
378
379
380
381
382
383
384
385
386
387
388
389
390
``` | ```md-code__content
def save_contents(self, dest_file):
"""Save html code of the window.
Args:
dest_file (str): full path of the destination html file
"""
if self.renderer:
html = \
self.renderer.Document.Body.OuterHtml.encode('ascii', 'ignore')
doc_txt = self.renderer.DocumentText
full_html = doc_txt.lower().replace('', html)
with open(dest_file, 'w') as output_file:
output_file.write(full_html)
``` | ##### `open_url(dest_url)` Open url page in output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dest_url` | `str` | web url of the target page | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
392
393
394
395
396
397
398
399
``` | ```md-code__content
def open_url(self, dest_url):
"""Open url page in output window.
Args:
dest_url (str): web url of the target page
"""
if self.renderer:
self.renderer.Navigate(dest_url, False)
``` | ##### `open_page(dest_file)` Open html page in output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dest_file` | `str` | full path of the target html file | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
401
402
403
404
405
406
407
408
``` | ```md-code__content
def open_page(self, dest_file):
"""Open html page in output window.
Args:
dest_file (str): full path of the target html file
"""
self.show()
self.open_url('file:///' + dest_file)
``` | ##### `update_progress(cur_value, max_value)` Activate and update the output window progress bar. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cur_value` | `float` | current progress value e.g. 50 | _required_ | | `max_value` | `float` | total value e.g. 100 | _required_ | Examples: ```md-code__content output = pyrevit.output.get_output() for i in range(100): output.update_progress(i, 100) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
``` | ````md-code__content
def update_progress(self, cur_value, max_value):
"""Activate and update the output window progress bar.
Args:
cur_value (float): current progress value e.g. 50
max_value (float): total value e.g. 100
Examples:
```python
output = pyrevit.output.get_output()
for i in range(100):
output.update_progress(i, 100)
```
"""
if self.window:
self.window.UpdateActivityBar(cur_value, max_value)
```` | ##### `reset_progress()` Reset output window progress bar to zero. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
427
428
429
430
``` | ```md-code__content
def reset_progress(self):
"""Reset output window progress bar to zero."""
if self.window:
self.window.UpdateActivityBar(0, 1)
``` | ##### `hide_progress()` Hide output window progress bar. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
432
433
434
435
``` | ```md-code__content
def hide_progress(self):
"""Hide output window progress bar."""
if self.window:
self.window.SetActivityBarVisibility(False)
``` | ##### `unhide_progress()` Unhide output window progress bar. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
437
438
439
440
``` | ```md-code__content
def unhide_progress(self):
"""Unhide output window progress bar."""
if self.window:
self.window.SetActivityBarVisibility(True)
``` | ##### `indeterminate_progress(state)` Show or hide indeterminate progress bar. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
442
443
444
445
``` | ```md-code__content
def indeterminate_progress(self, state):
"""Show or hide indeterminate progress bar."""
if self.window:
self.window.UpdateActivityBar(state)
``` | ##### `show_logpanel()` Show output window logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
447
448
449
450
``` | ```md-code__content
def show_logpanel(self):
"""Show output window logging panel."""
if self.window:
self.window.SetActivityBarVisibility(True)
``` | ##### `hide_logpanel()` Hide output window logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
452
453
454
455
456
``` | ```md-code__content
def hide_logpanel(self):
"""Hide output window logging panel."""
if self.window:
self.show_logpanel()
self.window.SetActivityBarVisibility(False)
``` | ##### `log_debug(message)` Report DEBUG message into output logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
458
459
460
461
462
``` | ```md-code__content
def log_debug(self, message):
"""Report DEBUG message into output logging panel."""
if self.window:
self.show_logpanel()
self.window.activityBar.ConsoleLog(message)
``` | ##### `log_success(message)` Report SUCCESS message into output logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
464
465
466
467
468
``` | ```md-code__content
def log_success(self, message):
"""Report SUCCESS message into output logging panel."""
if self.window:
self.show_logpanel()
self.window.activityBar.ConsoleLogOK(message)
``` | ##### `log_info(message)` Report INFO message into output logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
470
471
472
473
474
``` | ```md-code__content
def log_info(self, message):
"""Report INFO message into output logging panel."""
if self.window:
self.show_logpanel()
self.window.activityBar.ConsoleLogInfo(message)
``` | ##### `log_warning(message)` Report WARNING message into output logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
476
477
478
479
480
``` | ```md-code__content
def log_warning(self, message):
"""Report WARNING message into output logging panel."""
if self.window:
self.show_logpanel()
self.window.activityBar.ConsoleLogWarning(message)
``` | ##### `log_error(message)` Report ERROR message into output logging panel. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
482
483
484
485
486
``` | ```md-code__content
def log_error(self, message):
"""Report ERROR message into output logging panel."""
if self.window:
self.show_logpanel()
self.window.activityBar.ConsoleLogError(message)
``` | ##### `set_icon(iconpath)` Sets icon on the output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
488
489
490
491
``` | ```md-code__content
def set_icon(self, iconpath):
"""Sets icon on the output window."""
if self.window:
self.window.SetIcon(iconpath)
``` | ##### `reset_icon()` Sets icon on the output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
493
494
495
496
``` | ```md-code__content
def reset_icon(self):
"""Sets icon on the output window."""
if self.window:
self.window.ResetIcon()
``` | ##### `print_html(html_str)``staticmethod` Add the html code to the output window. Examples: ```md-code__content output = pyrevit.output.get_output() output.print_html('Title') ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
498
499
500
501
502
503
504
505
506
507
508
509
``` | ````md-code__content
@staticmethod
def print_html(html_str):
"""Add the html code to the output window.
Examples:
```python
output = pyrevit.output.get_output()
output.print_html('Title')
```
"""
print(coreutils.prepare_html_str(html_str),
end="")
```` | ##### `print_code(code_str)``staticmethod` Print code to the output window with special formatting. Examples: ```md-code__content output = pyrevit.output.get_output() output.print_code('value = 12') ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
``` | ````md-code__content
@staticmethod
def print_code(code_str):
"""Print code to the output window with special formatting.
Examples:
```python
output = pyrevit.output.get_output()
output.print_code('value = 12')
```
"""
code_div = '
{}
'
print(
coreutils.prepare_html_str(
code_div.format(
code_str.replace(' ', ' '*4)
)
),
end=""
)
```` | ##### `print_md(md_str)``staticmethod` Process markdown code and print to output window. Examples: ```md-code__content output = pyrevit.output.get_output() output.print_md('### Title') ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
``` | ````md-code__content
@staticmethod
def print_md(md_str):
"""Process markdown code and print to output window.
Examples:
```python
output = pyrevit.output.get_output()
output.print_md('### Title')
```
"""
tables_ext = 'pyrevit.coreutils.markdown.extensions.tables'
markdown_html = markdown.markdown(md_str, extensions=[tables_ext])
markdown_html = markdown_html.replace('\n', '').replace('\r', '')
html_code = coreutils.prepare_html_str(markdown_html)
print(html_code, end="")
```` | ##### `print_table(table_data, columns=None, formats=None, title='', last_line_style='')` Print provided data in a table in output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `table_data` | `list[iterable[Any]]` | 2D array of data | _required_ | | `title` | `str` | table title | `''` | | `columns` | `list[str]` | list of column names | `None` | | `formats` | `list[str]` | column data formats | `None` | | `last_line_style` | `str` | css style of last row | `''` | Examples: ```md-code__content data = [\ ['row1', 'data', 'data', 80 ],\ ['row2', 'data', 'data', 45 ],\ ] output.print_table( table_data=data, title="Example Table", columns=["Row Name", "Column 1", "Column 2", "Percentage"], formats=['', '', '', '{}%'], last_line_style='color:red;' ) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
``` | ````md-code__content
def print_table(self, table_data, columns=None, formats=None,
title='', last_line_style=''):
"""Print provided data in a table in output window.
Args:
table_data (list[iterable[Any]]): 2D array of data
title (str): table title
columns (list[str]): list of column names
formats (list[str]): column data formats
last_line_style (str): css style of last row
Examples:
```python
data = [
['row1', 'data', 'data', 80 ],
['row2', 'data', 'data', 45 ],
]
output.print_table(
table_data=data,
title="Example Table",
columns=["Row Name", "Column 1", "Column 2", "Percentage"],
formats=['', '', '', '{}%'],
last_line_style='color:red;'
)
```
"""
if not columns:
columns = []
if not formats:
formats = []
if last_line_style:
self.add_style('tr:last-child {{ {style} }}'
.format(style=last_line_style))
zipper = itertools.izip_longest #pylint: disable=E1101
adjust_base_col = '|'
adjust_extra_col = ':---|'
base_col = '|'
extra_col = '{data}|'
# find max column count
max_col = max([len(x) for x in table_data])
header = ''
if columns:
header = base_col
for idx, col_name in zipper(range(max_col), columns, fillvalue=''): #pylint: disable=W0612
header += extra_col.format(data=col_name)
header += '\n'
justifier = adjust_base_col
for idx in range(max_col):
justifier += adjust_extra_col
justifier += '\n'
rows = ''
for entry in table_data:
row = base_col
for idx, attrib, attr_format \
in zipper(range(max_col), entry, formats, fillvalue=''):
if attr_format:
value = attr_format.format(attrib)
else:
value = attrib
row += extra_col.format(data=value)
rows += row + '\n'
table = header + justifier + rows
self.print_md('### {title}'.format(title=title))
self.print_md(table)
```` | ##### `print_image(image_path)` Prints given image to the output. Examples: ```md-code__content output = pyrevit.output.get_output() output.print_image(r'C:\image.gif') ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
621
622
623
624
625
626
627
628
629
630
631
632
633
634
``` | ````md-code__content
def print_image(self, image_path):
r"""Prints given image to the output.
Examples:
```python
output = pyrevit.output.get_output()
output.print_image(r'C:\image.gif')
```
"""
self.print_html(
"".format(
image_path
)
)
```` | ##### `insert_divider(level='')` Add horizontal rule to the output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
636
637
638
``` | ```md-code__content
def insert_divider(self, level=''):
"""Add horizontal rule to the output window."""
self.print_md('%s\n-----' % level)
``` | ##### `next_page()` Add hidden next page tag to the output window. This is helpful to silently separate the output to multiple pages for better printing. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
640
641
642
643
644
645
646
``` | ```md-code__content
def next_page(self):
"""Add hidden next page tag to the output window.
This is helpful to silently separate the output to multiple pages
for better printing.
"""
self.print_html('
 
')
``` | ##### `linkify(element_ids, title=None)``staticmethod` Create clickable link for the provided element ids. This method, creates the link but does not print it directly. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_ids` | `ElementId | list[ElementId]` | single or multiple ids | _required_ | | `title` | `str` | tile of the link. defaults to list of element ids | `None` | Returns: | Type | Description | | --- | --- | | `str` | clickable link | Examples: ```md-code__content output = pyrevit.output.get_output() for idx, elid in enumerate(element_ids): print('{}: {}'.format(idx+1, output.linkify(elid))) ``` Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
``` | ````md-code__content
@staticmethod
def linkify(element_ids, title=None):
"""Create clickable link for the provided element ids.
This method, creates the link but does not print it directly.
Args:
element_ids (ElementId | list[ElementId]): single or multiple ids
title (str): tile of the link. defaults to list of element ids
Returns:
(str): clickable link
Examples:
```python
output = pyrevit.output.get_output()
for idx, elid in enumerate(element_ids):
print('{}: {}'.format(idx+1, output.linkify(elid)))
```
"""
return coreutils.prepare_html_str(
linkmaker.make_link(element_ids, contents=title)
)
```` | ##### `make_chart(version=None)` :obj: `PyRevitOutputChart`: Return chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
673
674
675
``` | ```md-code__content
def make_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return chart object."""
return charts.PyRevitOutputChart(self, version=version)
``` | ##### `make_line_chart(version=None)` :obj: `PyRevitOutputChart`: Return line chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
677
678
679
680
681
682
683
``` | ```md-code__content
def make_line_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return line chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.LINE_CHART,
version=version
)
``` | ##### `make_stacked_chart(version=None)` :obj: `PyRevitOutputChart`: Return stacked chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
685
686
687
688
689
690
691
692
693
``` | ```md-code__content
def make_stacked_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return stacked chart object."""
chart = charts.PyRevitOutputChart(
self,
chart_type=charts.LINE_CHART,
version=version
)
chart.options.scales = {'yAxes': [{'stacked': True, }]}
return chart
``` | ##### `make_bar_chart(version=None)` :obj: `PyRevitOutputChart`: Return bar chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
695
696
697
698
699
700
701
``` | ```md-code__content
def make_bar_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return bar chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.BAR_CHART,
version=version
)
``` | ##### `make_radar_chart(version=None)` :obj: `PyRevitOutputChart`: Return radar chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
703
704
705
706
707
708
709
``` | ```md-code__content
def make_radar_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return radar chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.RADAR_CHART,
version=version
)
``` | ##### `make_polar_chart(version=None)` :obj: `PyRevitOutputChart`: Return polar chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
711
712
713
714
715
716
717
``` | ```md-code__content
def make_polar_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return polar chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.POLAR_CHART,
version=version
)
``` | ##### `make_pie_chart(version=None)` :obj: `PyRevitOutputChart`: Return pie chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
719
720
721
722
723
724
725
``` | ```md-code__content
def make_pie_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return pie chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.PIE_CHART,
version=version
)
``` | ##### `make_doughnut_chart(version=None)` :obj: `PyRevitOutputChart`: Return dougnut chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
727
728
729
730
731
732
733
``` | ```md-code__content
def make_doughnut_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return dougnut chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.DOUGHNUT_CHART,
version=version
)
``` | ##### `make_bubble_chart(version=None)` :obj: `PyRevitOutputChart`: Return bubble chart object. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
735
736
737
738
739
740
741
``` | ```md-code__content
def make_bubble_chart(self, version=None):
""":obj:`PyRevitOutputChart`: Return bubble chart object."""
return charts.PyRevitOutputChart(
self,
chart_type=charts.BUBBLE_CHART,
version=version
)
``` | ## Functions ### `docclosing_eventhandler(sender, args)` Close all output window on document closing. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
45
46
47
``` | ```md-code__content
def docclosing_eventhandler(sender, args): #pylint: disable=W0613
"""Close all output window on document closing."""
ScriptConsoleManager.CloseActiveOutputWindows()
``` | ### `setup_output_closer()` Setup document closing event listener. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
50
51
52
53
54
55
``` | ```md-code__content
def setup_output_closer():
"""Setup document closing event listener."""
HOST_APP.app.DocumentClosing += \
framework.EventHandler[DB.Events.DocumentClosingEventArgs](
docclosing_eventhandler
)
``` | ### `set_stylesheet(stylesheet)` Set active css stylesheet used by output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `stylesheet` | `str` | full path to stylesheet file | _required_ | Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
58
59
60
61
62
63
64
65
66
``` | ```md-code__content
def set_stylesheet(stylesheet):
"""Set active css stylesheet used by output window.
Args:
stylesheet (str): full path to stylesheet file
"""
if op.isfile(stylesheet):
envvars.set_pyrevit_env_var(envvars.OUTPUT_STYLESHEET_ENVVAR,
stylesheet)
``` | ### `get_stylesheet()` Return active css stylesheet used by output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
72
73
74
``` | ```md-code__content
def get_stylesheet():
"""Return active css stylesheet used by output window."""
return envvars.get_pyrevit_env_var(envvars.OUTPUT_STYLESHEET_ENVVAR)
``` | ### `get_default_stylesheet()` Return default css stylesheet used by output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
77
78
79
``` | ```md-code__content
def get_default_stylesheet():
"""Return default css stylesheet used by output window."""
return op.join(op.dirname(__file__), DEFAULT_STYLESHEET_NAME)
``` | ### `reset_stylesheet()` Reset active stylesheet to default. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
82
83
84
85
``` | ```md-code__content
def reset_stylesheet():
"""Reset active stylesheet to default."""
envvars.set_pyrevit_env_var(envvars.OUTPUT_STYLESHEET_ENVVAR,
get_default_stylesheet())
``` | ### `get_output()` :obj: `pyrevit.output.PyRevitOutputWindow` : Return output window. Source code in `pyrevitlib/pyrevit/output/__init__.py` | | | | --- | --- | | ```
744
745
746
``` | ```md-code__content
def get_output():
""":obj:`pyrevit.output.PyRevitOutputWindow` : Return output window."""
return PyRevitOutputWindow()
``` | Back to top ## User Configuration Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/userconfig/#pyrevit.userconfig) # userconfig Handle reading and parsing, writing and saving of all user configurations. This module handles the reading and writing of the pyRevit configuration files. It's been used extensively by pyRevit sub-modules. user\_config is set up automatically in the global scope by this module and can be imported into scripts and other modules to access the default configurations. All other modules use this module to query user config. Examples: ```md-code__content from pyrevit.userconfig import user_config user_config.add_section('newsection') user_config.newsection.property = value user_config.newsection.get_option('property', default_value) user_config.save_changes() ``` The user\_config object is also the destination for reading and writing configuration by pyRevit scripts through :func: `get_config` of :mod: `pyrevit.script` module. Here is the function source: .. literalinclude:: ../../pyrevitlib/pyrevit/script.py :pyobject: get\_config Examples: ```md-code__content from pyrevit import script cfg = script.get_config() cfg.property = value cfg.get_option('property', default_value) script.save_config() ``` ## Attributes ### `DEFAULT_CSV_SEPARATOR = ','``module-attribute` ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `CONSTS = PyRevit.PyRevitConsts``module-attribute` ### `LOCAL_CONFIG_FILE = find_config_file(HOME_DIR)``module-attribute` ### `ADMIN_CONFIG_FILE = find_config_file(PYREVIT_ALLUSER_APP_DIR)``module-attribute` ### `USER_CONFIG_FILE = find_config_file(PYREVIT_APP_DIR)``module-attribute` ### `CONFIG_TYPE = 'Seed'``module-attribute` ### `CONFIG_FILE = find_config_file(PYREVIT_APP_DIR)``module-attribute` ### `user_config = PyRevitConfig(cfg_file_path=CONFIG_FILE, config_type=CONFIG_TYPE)``module-attribute` ## Classes ### `PyRevitConfig(cfg_file_path=None, config_type='Unknown')` Bases: `PyRevitConfigParser` Provide read/write access to pyRevit configuration. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cfg_file_path` | `str` | full path to config file to be used. | `None` | | `config_type` | `str` | type of config file | `'Unknown'` | Examples: ```md-code__content cfg = PyRevitConfig(cfg_file_path) cfg.add_section('sectionname') cfg.sectionname.property = value cfg.sectionname.get_option('property', default_value) cfg.save_changes() ``` Load settings from provided config file and setup parser. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
81
82
83
84
85
86
87
88
89
90
``` | ```md-code__content
def __init__(self, cfg_file_path=None, config_type='Unknown'):
"""Load settings from provided config file and setup parser."""
# try opening and reading config file in order.
super(PyRevitConfig, self).__init__(cfg_file_path=cfg_file_path)
# set log mode on the logger module based on
# user settings (overriding the defaults)
self._update_env()
self._admin = config_type == 'Admin'
self.config_type = config_type
``` | #### Attributes ##### `config_type = config_type``instance-attribute` ##### `config_file``property` Current config file path. ##### `environment``property` Environment section. ##### `core``property` Core section. ##### `routes``property` Routes section. ##### `telemetry``property` Telemetry section. ##### `bin_cache``property``writable` "Whether to use the cache for extensions. ##### `check_updates``property``writable` Whether to check for updates. ##### `auto_update``property``writable` Whether to automatically update pyRevit. ##### `rocket_mode``property``writable` Whether to enable rocket mode. ##### `log_level``property``writable` Logging level. ##### `file_logging``property``writable` Whether to enable file logging. ##### `startuplog_timeout``property``writable` Timeout for the startup log. ##### `required_host_build``property``writable` Host build required to run the commands. ##### `min_host_drivefreespace``property``writable` Minimum free space for running the commands. ##### `load_beta``property``writable` Whether to load commands in beta. ##### `cpython_engine_version``property``writable` CPython engine version to use. ##### `user_locale``property``writable` User locale. ##### `output_stylesheet``property``writable` Stylesheet used for output. ##### `routes_host``property``writable` Routes API host. ##### `routes_port``property``writable` API routes port. ##### `load_core_api``property``writable` Whether to load pyRevit core api. ##### `telemetry_utc_timestamp``property``writable` Whether to use UTC timestamps in telemetry. ##### `telemetry_status``property``writable` Telemetry status. ##### `telemetry_file_dir``property``writable` Telemetry file directory. ##### `telemetry_server_url``property``writable` Telemetry server URL. ##### `telemetry_include_hooks``property``writable` Whether to include hooks in telemetry. ##### `apptelemetry_status``property``writable` Telemetry status. ##### `apptelemetry_server_url``property``writable` App telemetry server URL. ##### `apptelemetry_event_flags``property``writable` Telemetry event flags. ##### `user_can_update``property``writable` Whether the user can update pyRevit repos. ##### `user_can_extend``property``writable` Whether the user can manage pyRevit Extensions. ##### `user_can_config``property``writable` Whether the user can access the configuration. ##### `colorize_docs``property``writable` Whether to enable the document colorizer. ##### `tooltip_debug_info``property``writable` Whether to append debug info on tooltips. ##### `routes_server``property``writable` Whether the server routes are enabled. ##### `respect_language_direction``property``writable` Whether the system respects the language direction. ##### `is_readonly``property` bool: whether the config is read only. #### Functions ##### `get_config_file_hash()` Get calculated unique hash for this config. Returns: | Type | Description | | --- | --- | | `str` | hash of the config. | Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
170
171
172
173
174
175
176
177
178
179
``` | ```md-code__content
def get_config_file_hash(self):
"""Get calculated unique hash for this config.
Returns:
(str): hash of the config.
"""
with codecs.open(self._cfg_file_path, 'r', 'utf-8') as cfg_file:
cfg_hash = coreutils.get_str_hash(cfg_file.read())
return cfg_hash
``` | ##### `has_section(section_name)` Check if config contains given section. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
181
182
183
184
185
186
187
``` | ```md-code__content
def has_section(self, section_name):
"""Check if config contains given section."""
try:
self.get_section(section_name)
return True
except Exception:
return False
``` | ##### `add_section(section_name)` Add section with given name to config. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
189
190
191
192
``` | ```md-code__content
def add_section(self, section_name):
"""Add section with given name to config."""
self._parser.add_section(section_name)
return PyRevitConfigSectionParser(self._parser, section_name)
``` | ##### `get_section(section_name)` Get section with given name. Raises: | Type | Description | | --- | --- | | `AttributeError` | if section is missing | Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
``` | ```md-code__content
def get_section(self, section_name):
"""Get section with given name.
Raises:
AttributeError: if section is missing
"""
# check is section with full name is available
if self._parser.has_section(section_name):
return PyRevitConfigSectionParser(self._parser, section_name)
# if not try to match with section_name.subsection
# if there is a section_name.subsection defined, that should be
# the sign that the section exists
# section obj then supports getting all subsections
for cfg_section_name in self._parser.sections():
master_section = coreutils.get_canonical_parts(cfg_section_name)[0]
if section_name == master_section:
return PyRevitConfigSectionParser(self._parser,
master_section)
# if no match happened then raise exception
raise AttributeError('Section does not exist in config file.')
``` | ##### `remove_section(section_name)` Remove section from config. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
217
218
219
220
221
222
``` | ```md-code__content
def remove_section(self, section_name):
"""Remove section from config."""
cfg_section = self.get_section(section_name)
for cfg_subsection in cfg_section.get_subsections():
self._parser.remove_section(cfg_subsection.header)
self._parser.remove_section(cfg_section.header)
``` | ##### `reload(cfg_file_path=None)` Reload config from original or given file. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
224
225
226
227
228
229
230
231
232
233
234
``` | ```md-code__content
def reload(self, cfg_file_path=None):
"""Reload config from original or given file."""
try:
with codecs.open(cfg_file_path \
or self._cfg_file_path, 'r', 'utf-8') as cfg_file:
try:
self._parser.readfp(cfg_file)
except AttributeError:
self._parser.read_file(cfg_file)
except (OSError, IOError):
raise PyRevitIOError()
``` | ##### `save(cfg_file_path=None)` Save config to original or given file. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
236
237
238
239
240
241
242
243
``` | ```md-code__content
def save(self, cfg_file_path=None):
"""Save config to original or given file."""
try:
with codecs.open(cfg_file_path \
or self._cfg_file_path, 'w', 'utf-8') as cfg_file:
self._parser.write(cfg_file)
except (OSError, IOError):
raise PyRevitIOError()
``` | ##### `get_config_version()` Return version of config file used for change detection. Returns: | Type | Description | | --- | --- | | `str` | hash of the config file | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
617
618
619
620
621
622
623
``` | ```md-code__content
def get_config_version(self):
"""Return version of config file used for change detection.
Returns:
(str): hash of the config file
"""
return self.get_config_file_hash()
``` | ##### `get_thirdparty_ext_root_dirs(include_default=True)` Return a list of external extension directories set by the user. Returns: | Type | Description | | --- | --- | | `list[str]` | External user extension directories. | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
``` | ```md-code__content
def get_thirdparty_ext_root_dirs(self, include_default=True):
"""Return a list of external extension directories set by the user.
Returns:
(list[str]): External user extension directories.
"""
dir_list = set()
if include_default:
# add default ext path
dir_list.add(THIRDPARTY_EXTENSIONS_DEFAULT_DIR)
try:
dir_list.update([
op.expandvars(op.normpath(x))
for x in self.core.get_option(
CONSTS.ConfigsUserExtensionsKey,
default_value=[]
)])
except Exception as read_err:
mlogger.error('Error reading list of user extension folders. | %s',
read_err)
return [x for x in dir_list if op.exists(x)]
``` | ##### `get_ext_root_dirs()` Return a list of all extension directories. Returns: | Type | Description | | --- | --- | | `list[str]` | user extension directories. | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
648
649
650
651
652
653
654
655
656
657
658
659
``` | ```md-code__content
def get_ext_root_dirs(self):
"""Return a list of all extension directories.
Returns:
(list[str]): user extension directories.
"""
dir_list = set()
if op.exists(EXTENSIONS_DEFAULT_DIR):
dir_list.add(EXTENSIONS_DEFAULT_DIR)
dir_list.update(self.get_thirdparty_ext_root_dirs())
return list(dir_list)
``` | ##### `get_ext_sources()` Return a list of extension definition source files. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
661
662
663
664
665
666
667
``` | ```md-code__content
def get_ext_sources(self):
"""Return a list of extension definition source files."""
ext_sources = self.environment.get_option(
CONSTS.EnvConfigsExtensionLookupSourcesKey,
default_value=[],
)
return list(set(ext_sources))
``` | ##### `set_thirdparty_ext_root_dirs(path_list)` Updates list of external extension directories in config file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `path_list` | `list[str]` | list of external extension paths | _required_ | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
``` | ```md-code__content
def set_thirdparty_ext_root_dirs(self, path_list):
"""Updates list of external extension directories in config file.
Args:
path_list (list[str]): list of external extension paths
"""
for ext_path in path_list:
if not op.exists(ext_path):
raise PyRevitException("Path \"%s\" does not exist." % ext_path)
try:
self.core.userextensions = \
[op.normpath(x) for x in path_list]
except Exception as write_err:
mlogger.error('Error setting list of user extension folders. | %s',
write_err)
``` | ##### `get_current_attachment()` Return current pyRevit attachment. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
686
687
688
689
690
691
``` | ```md-code__content
def get_current_attachment(self):
"""Return current pyRevit attachment."""
try:
return PyRevit.PyRevitAttachments.GetAttached(int(HOST_APP.version))
except PyRevitException as ex:
mlogger.error('Error getting current attachment. | %s', ex)
``` | ##### `get_active_cpython_engine()` Return active cpython engine. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
``` | ```md-code__content
def get_active_cpython_engine(self):
"""Return active cpython engine."""
# try to find attachment and get engines from the clone
attachment = self.get_current_attachment()
if attachment and attachment.Clone:
clone = attachment.Clone
else:
# if can not find attachment, instantiate a temp clone
try:
clone = PyRevit.PyRevitClone(clonePath=HOME_DIR)
except Exception as cEx:
mlogger.debug('Can not create clone from path: %s', str(cEx))
clone = None
# find cpython engines
engines = clone.GetCPythonEngines() if clone else []
cpy_engines_dict = {x.Version: x for x in engines}
mlogger.debug('cpython engines dict: %s', cpy_engines_dict)
if not cpy_engines_dict:
mlogger.error(
'Can not determine cpython engines for current attachment: %s',
attachment
)
return None
# grab cpython engine configured to be used by user
try:
cpyengine_ver = int(self.cpython_engine_version)
except (ValueError, TypeError):
cpyengine_ver = 000
try:
return cpy_engines_dict[cpyengine_ver]
except KeyError:
# return the latest cpython engine
return max(cpy_engines_dict.values(), key=lambda x: x.Version.Version)
``` | ##### `set_active_cpython_engine(pyrevit_engine)` Set the active CPython engine. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrevit_engine` | `PyRevitEngine` | python engine to set as active | _required_ | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
729
730
731
732
733
734
735
``` | ```md-code__content
def set_active_cpython_engine(self, pyrevit_engine):
"""Set the active CPython engine.
Args:
pyrevit_engine (PyRevitEngine): python engine to set as active
"""
self.cpython_engine_version = pyrevit_engine.Version
``` | ##### `save_changes()` Save user config into associated config file. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
742
743
744
745
746
747
748
749
750
751
752
753
754
``` | ```md-code__content
def save_changes(self):
"""Save user config into associated config file."""
if not self._admin and self.config_file:
try:
super(PyRevitConfig, self).save()
except Exception as save_err:
mlogger.error('Can not save user config to: %s | %s',
self.config_file, save_err)
# adjust environment per user configurations
self._update_env()
else:
mlogger.debug('Config is in admin mode. Skipping save.')
``` | ##### `get_list_separator()``staticmethod` Get list separator defined in user os regional settings. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
756
757
758
759
760
761
762
763
764
765
``` | ```md-code__content
@staticmethod
def get_list_separator():
"""Get list separator defined in user os regional settings."""
intkey = coreutils.get_reg_key(wr.HKEY_CURRENT_USER,
r'Control Panel\International')
if intkey:
try:
return wr.QueryValueEx(intkey, 'sList')[0]
except Exception:
return DEFAULT_CSV_SEPARATOR
``` | ## Functions ### `find_config_file(target_path)` Find config file in target path. Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
768
769
770
``` | ```md-code__content
def find_config_file(target_path):
"""Find config file in target path."""
return PyRevit.PyRevitConsts.FindConfigFileInDirectory(target_path)
``` | ### `verify_configs(config_file_path=None)` Create a user settings file. if config\_file\_path is not provided, configs will be in memory only Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `config_file_path` | `str` | config file full name and path | `None` | Returns: | Type | Description | | --- | --- | | `PyRevitConfig` | pyRevit config file handler | Source code in `pyrevitlib/pyrevit/userconfig.py` | | | | --- | --- | | ```
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
``` | ```md-code__content
def verify_configs(config_file_path=None):
"""Create a user settings file.
if config_file_path is not provided, configs will be in memory only
Args:
config_file_path (str, optional): config file full name and path
Returns:
(pyrevit.userconfig.PyRevitConfig): pyRevit config file handler
"""
if config_file_path:
mlogger.debug('Creating default config file at: %s', config_file_path)
coreutils.touch(config_file_path)
try:
parser = PyRevitConfig(cfg_file_path=config_file_path)
except Exception as read_err:
# can not create default user config file under appdata folder
mlogger.warning('Can not create config file under: %s | %s',
config_file_path, read_err)
parser = PyRevitConfig()
return parser
``` | Back to top ## pyRevit Architecture Guide [Skip to content](https://docs.pyrevitlabs.io/architecture/#understanding-pyrevit-architecture) # Understanding pyRevit Architecture This guide provides an overview of pyRevit’s architecture to help new contributors understand how the software works. Whether you want to create tools, troubleshoot issues, or contribute code, understanding these components will help you navigate the project. ## Components of pyRevit 1. **pyRevit Add-In (pyRevitLoader)** - A small piece of C# code that starts pyRevit inside Revit. - It loads a Python script using the IronPython engine, which handles the rest of pyRevit’s functionality. 2. **pyRevit python Libraries (pyrevitlibs)** - Python packages that simplify working with the .NET Revit API. - Provide tools to create ribbon buttons, run scripts, and more. 3. **Extensions** - These are the tools and features users see inside Revit. - They are mostly written in python, but can also be C#/VB.NET scripts, dynamo projects, and so on - Bundled extensions appear in the "pyRevit" tab, offering many tools. - Users can add extensions by: - Enabling listed extensions in `dev/extensions/extensions.json` via the “Extensions” button in pyRevit. - Creating custom extensions and adding their paths to the configuration. 4. **pyRevit Command-Line Interface (CLI)** - A tool for managing configurations, running scripts in bulk, and troubleshooting. - Useful for corporate setups and advanced users. 5. **Telemetry Server** - A small server (written in Go) that tracks usage data of pyRevit tools. - Stores data in MongoDB or PostgreSQL for business intelligence. ## How pyRevit Loads in Revit TL;DR: - Revit reads the `.addin` manifest in the Addins folders - The `.addin` manifest points to `pyRevitLoader.dll` - `pyRevitLoader.dll` launches `pyrevitloader.py` inside an IronPython environment - `pyrevitloader.py` calls functions from the `pyrevit` python package to build the UI and the buttons commands. ### .addin Manifest - The installer creates a file with `.addin` extension, called manifest, in the Revit Addins folder, instructing Revit to load pyRevit when it starts. - The Addins folder can be located in one of these paths, depending on pyRevit installation: - `C:\ProgramData\Autodesk\Revit\Addins` (for all users) - `%APPDATA%\Autodesk\Revit\Addins` (for the current user only) - The manifest points to `pyRevitLoader.dll`, which acts as the entry point for pyRevit. ### pyRevitLoader.dll The `pyRevitLoader.dll` file is a small C# program that: - Ensures required .NET assemblies are loaded. - Loads the IronPython engine and runs pyRevit’s Python startup script ( `pyrevitloader.py`). Info the source code is in `PyRevitLoaderApplication.cs` and it is an implementation of the Revit API `IExternalApplication` _interface_ (the standard way to create a plugin for Revit). There are multiple versions of `pyRevitLoader.dll` to support: - different Revit versions: - One for Revit 2025 and newer, built with .NET 8. - Another for older Revit versions, built with the .NET Framework. - different IronPython versions; to this date: - version 2.7.12, the default one - version 3.4.0, more recent but not fully tested. They share the same source code, but are _compiled against_ the different .net runtimes and IronPython versions. Note Since we cannot have multiple IronPython engines running at the same time, if the user switches the engine in the configuration, pyRevit will change the `.addin` manifest mentioned above to point to the correct dll path. It may be that sometimes the addin is not created correctly or points to the wrong path, and this is why most of the times the `pyrevit attach` command solves the installation issues. ### Startup Script: `pyrevitloader.py` This Python script is the first code executed by pyRevit inside Revit. It: - Sets up environment variables. - Initializes the logging system and prepares the script console - Checks for updates if enabled, pulling changes for pyRevit and extensions. - Loads extensions and creates UI elements like ribbons and buttons (see [below](https://docs.pyrevitlabs.io/architecture/#extensions-discovery)). - Activates hooks, which enable features like event-driven scripts. - Initializes API routes and Telemetry, if enabled Info `pyrevitloader.py` is a small script that just calls the [pyrevit.loader.sessionmgr.load\_session](https://docs.pyrevitlabs.io/reference/pyrevit/loader/sessionmgr/#pyrevit.loader.sessionmgr.load_session "load_session()") function. That function is responsible to do all the things mentioned above. ### Extensions discovery - pyRevit scans known paths and user defined folders to find extensions. - For each extension, it builds a .net assembly to create buttons, tabs, and other UI elements. Info Extensions directories are detected by [pyrevit.userconfig.PyRevitConfig.get\_ext\_root\_dirs](https://docs.pyrevitlabs.io/reference/pyrevit/userconfig/#pyrevit.userconfig.PyRevitConfig.get_ext_root_dirs "get_ext_root_dirs()"). Extension components discovery is performed by [pyrevit.extensions.extensionmgr.get\_installed\_ui\_extensions](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/extensionmgr/#pyrevit.extensions.extensionmgr.get_installed_ui_extensions "get_installed_ui_extensions()"). Assemblies are generated by [pyrevit.loader.asmmaker](https://docs.pyrevitlabs.io/reference/pyrevit/loader/asmmaker/#pyrevit.loader.asmmaker) with types from [pyrevit.runtime.create\_type](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/#pyrevit.runtime.create_type "create_type(modulebuilder, type_class, class_name, custom_attr_list, *args)"). ## How pyRevit Commands run TL;DR: Command execution is handled by the c# project `pyRevitLabs.Pyrevit.Runtime` Each button generated by the [Extension discovery](https://docs.pyrevitlabs.io/architecture/#extensions-discovery) is bound to a command derived by the `ScriptCommand.cs` source code. This code deals with: - detecting the modifier keys hold while clicking the button, and change the behavior accordingly - calling `ScriptExcecutor.ExcecuteScript` passing the python script (or any other supportesd script) for the command Info The `ScriptCommand` class implements Revit’s `IExternalCommand` interface. The `Execute` method is the one called when you click the Ribbon button. In turn, the code in `ScriptExecutor.cs` calls the appropriate script engine based on the type of (IronPython, CPython, .NET, and so on). Info You can find the code of the engines in the files that end `Engine.cs`. Back to top ## Security Policy [Skip to content](https://docs.pyrevitlabs.io/SECURITY/#security-policy) # Security Policy > Note that the most up to date code is located in the develop branch. Every 6 months to 12 months, the develop branch is merged to the master branch and new releases are integrated. ## Reporting a Vulnerability **Please do not report security vulnerabilities through public pyRevit GitHub issues, discussions, or pull requests.** Instead, please send an email to eirannejad+pyrevitsecurity\[@\]gmail.com . Please include as much of the information listed below as you can to help us better understand and resolve the issue: - The type of issue (e.g., buffer overflow, SQL injection, or cross-site scripting) - Full paths of source file(s) related to the manifestation of the issue - The location of the affected source code (tag/branch/commit or direct URL) - Any special configuration required to reproduce the issue - Step-by-step instructions to reproduce the issue - Proof-of-concept or exploit code (if possible) - Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. Back to top ## Contributing to pyRevit # Contributing [See Contributing to pyRevit Source on pyRevit Wiki](https://pyrevitlabs.notion.site/Contributing-to-pyRevit-Source-6d25a5ac62c44bd9a0e9aefb8debefa2?pvs=4) Back to top ## Code of Conduct [Skip to content](https://docs.pyrevitlabs.io/CODE_OF_CONDUCT/#contributor-covenant-code-of-conduct) # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@pyrevitlabs.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq Back to top ## pyRevit Repository Structure [Skip to content](https://docs.pyrevitlabs.io/repo-organization/#repository-organization) # Repository organization The pyRevit repository is organized in the following folders: - `bin` contains the binaries (dll and other support files) for pyRevit; usually a source repository doesn't have these, but it was made like this to be able to switch pyRevit versions using clones. This may change in the future and we could get rid of most content of this folder. Note that in this folder there also are the python envrionments (for example the CPython dlls and core packages). - `dev` is where the c# code resides. - `docs` is for the automatic generation of the [documentation website](https://docs.pyrevitlabs.io/) - `extensions` holds the various pyRevit extensions; the pyRevitCore.extension is the one that build the `pyRevit` ribbon tab, the others can be enabled via the Extension button inside pyRevit itself. `pyRevitDevTools` is quite handy to run tests and check if pyRevit (and the modifications you'll do) is running fine. - `extras` are… extra files that can come in handy (icons and the dark mode generator are there to this date). - `licenses` contains all the licenses of the included third party projects. - `pyrevitlib` contains pyRevit and other related project's python libraries. It is usually the library that gets imported in the user scripts to ease the Revit API development. - `release` contains static assets needed to build the final product (pyrevit and pyrevit cli installers). - `site-packages` is the collection of third-party python packaces that are made available by pyRevit to the user. Given that the main python engine is IronPython 2.7.12, packages in that folder needs to be compatible with it. - `static` are assets for the website, youtube channels and so on, you can ignore it. Back to top ## pyRevit Developer Guide [Skip to content](https://docs.pyrevitlabs.io/dev-guide/#pyrevit-developers-guide) # pyRevit Developer's Guide This guide is designed to help new contributors set up their development environment, get familiar with the codebase, and start contributing to the project. Note This guide is for people that wants to get their hands dirty in the core pyRevit code, the part written in C#. It is not for the development of the python side. ## Requirements Before you begin, you'll need to set up your development environment with the following tools: ### Visual Studio Install Visual Studio 2022 and select: - under **workloads**, enable **.NET desktop development** - under ¨ **Individual components** make sure the following are selected: - .NET 8.0 Runtime (Long Term Support) - .NET Framework 4.7.2 Targeting Pack - .NET Framework 4.8 SDK - .NET Framework 4.8 Targeting Pack - .NET 3.1 Runtime (MahApps.Metro) - NuGet package manager - MSBuild ### Python 3 Make sure Python 3 is installed on your system. Download it from the [Python official website](https://www.python.org/downloads/). ### Pipenv This tool manages Python environments and dependencies. You can install Pipenv by running: ```md-code__content pip install pipenv ``` ## Git Setup To contribute to pyRevit, you'll need to set up your Git environment as follows: ### Fork the Repository Go to the [pyrevitlabs/pyrevit](https://github.com/pyrevitlabs/pyrevit) GitHub page and click on the "Fork" button to create your own copy of the repository. Make sure to uncheck the "Copy the master branch only" option, since we mostly use the develop branch to make changes. ### Clone Your Fork if you already have a copy of pyRevit or pyRevit CLI installed, you can use the command ```md-code__content pyrevit clone --source --dest --branch develop ``` As an example, I choose to call the clone "dev" and put it in "C:\\pyrevit", so my command becomes ```md-code__content pyrevit clone dev --source https:/gitlab.com/sanzoghenzo/pyrevit.git --dest c:\pyrevit --branch=develop ``` Note I will use the `dev` name in the following steps, make sure to replace it with the name of your choice. If you don't have pyrevit cli installed, or prefer to do things in the canonical way, follow these steps: 1. **Clone Your Fork**: Clone your forked repository to your local machine: ```md-code__content git clone ``` 2. **Enter pyRevit folder**: ```md-code__content cd pyrevit ``` 3. **Checkout the Develop Branch**: This is where active development happens, so make sure you're working on this branch: ```md-code__content git checkout develop ``` ### Set Upstream Remote Add the original pyrevitlabs repository as an "upstream" remote to keep your fork in sync: ```md-code__content git remote add upstream https://github.com/pyrevitlabs/pyrevit.git ``` You can choose any name for the remote, but "upstream" is a common convention. ### Retrieve the submodules At this time of writing, the pyRevit repository uses git submodules (stored in the `dev\modules` folder) to get some of its dependencies. Initialize and fetch them with the following commands: ```md-code__content git submodule update --init --recursive ``` Note you may have to repeat the `git submodule update` command when you switch to another existing branch, or when new commits in the develop branch update the dependencies. ## Initialize the pipenv environment This will create a python environment for running the toolchain scripts to build the various pyrevit components. ```md-code__content pipenv install ``` ## IDE Setup You have a couple of options for setting up your development environment: 1. **Visual Studio Code**: You can open the entire pyRevit directory in Visual Studio Code. This setup works well for Python development, but may lack some C#/.NET language support. 2. Recommended extensions: C#, Python, and GitLens. 3. **Visual Studio**: For full C#/.NET support, it's better to open a specific solution file ( `.sln`) in Visual Studio. This gives you access to language checks, autocompletion, and suggestions. 4. Open the solution that corresponds to the area of the project you're working on. But you can of course use your IDE of choice, such as Rider for .NET and pyCharm for python. ## Revit Setup To run and test your changes in Revit, follow these steps: 1. **Create a Clone**: If you cloned the git repository without the pyRevit CLI, you need to use it now to create a clone of your git directory: ```md-code__content pyrevit clones add dev ``` 1. **Attach the Clone**: Attach your clone to the default Revit installation: ```md-code__content pyrevit attach dev default --installed ``` Note the pyRevit dll paths have changed with pyrevit 5 (current WIP version), so you need to use the pyrevit CLI from a WIP installer for this to work. If you don't have it already, you can build the CLI from sources and run it with ```md-code__content pipenv run pyrevit build labs copy .\release\.pyrevitargs . .\bin\pyrevit.exe attach dev default --installed ``` ## Debugging Code Currently, you cannot use Visual Studio's "Run" button to debug pyRevit because of some build issues. Instead, follow this approach: 1. **Build the Project**: Open a command prompt or PowerShell, navigate to your git directory, and build the project in Debug mode: ```md-code__content pipenv run pyrevit build products Debug ``` 1. **Open the Solution in Visual Studio**: Once the DLLs are built, open the `pyRevitLabs.PyRevit.Runtime` solution in Visual Studio. 2. **Attach the Debugger**: Attach the Visual Studio debugger to the `revit.exe` process to start debugging: 3. Go to `Debug` \> `Attach to Process...` and select `revit.exe` from the list. ## Conclusion You're now ready to start contributing to pyRevit! Whether you're fixing bugs, adding new features, or improving documentation, your contributions are valuable. If you have any questions, feel free to reach out to the community through GitHub or other communication channels. Happy coding! Back to top ## pyRevit Configuration Guide [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/#pyrevit) # pyrevit pyRevit root level config for all pyrevit sub-modules. Examples: ```md-code__content from pyrevit import DB, UI from pyrevit import PyRevitException, PyRevitIOError # pyrevit module has global instance of the # _HostAppPostableCommand and _ExecutorParams classes already created # import and use them like below from pyrevit import HOST_APP from pyrevit import EXEC_PARAMS ``` ## Attributes ### `PYREVIT_ADDON_NAME = 'pyRevit'``module-attribute` ### `PYREVIT_CLI_NAME = 'pyrevit.exe'``module-attribute` ### `VERSION_STRING = version_file.read()``module-attribute` ### `matches = re.findall('(\\d+)\\.(\\d+)\\.(\\d+)\\.?(.+)?', VERSION_STRING)[0]``module-attribute` ### `BUILD_METADATA = ''``module-attribute` ### `VERSION_MAJOR = int(VERSION_MAJOR)``module-attribute` ### `VERSION_MINOR = int(VERSION_MINOR)``module-attribute` ### `VERSION_PATCH = int(VERSION_PATCH)``module-attribute` ### `HOME_DIR = op.dirname(op.dirname(op.dirname(__file__)))``module-attribute` ### `DOTNET_RUNTIME_ID = 'netcore' if compat.NETCORE else 'netfx'``module-attribute` ### `ROOT_BIN_DIR = op.join(HOME_DIR, 'bin')``module-attribute` ### `BIN_DIR = op.join(ROOT_BIN_DIR, DOTNET_RUNTIME_ID)``module-attribute` ### `MAIN_LIB_DIR = op.join(HOME_DIR, 'pyrevitlib')``module-attribute` ### `MISC_LIB_DIR = op.join(HOME_DIR, 'site-packages')``module-attribute` ### `MODULE_DIR = op.join(MAIN_LIB_DIR, 'pyrevit')``module-attribute` ### `LOADER_DIR = op.join(MODULE_DIR, 'loader')``module-attribute` ### `RUNTIME_DIR = op.join(MODULE_DIR, 'runtime')``module-attribute` ### `ADDIN_DIR = op.join(LOADER_DIR, 'addin')``module-attribute` ### `ENGINES_DIR = op.join(BIN_DIR, 'engines', eng.EngineVersion)``module-attribute` ### `PYREVIT_CLI_PATH = op.join(HOME_DIR, 'bin', PYREVIT_CLI_NAME)``module-attribute` ### `TRACEBACK_TITLE = 'Traceback:'``module-attribute` ### `HOST_APP = _HostApplication()``module-attribute` ### `EXEC_PARAMS = _ExecutorParams()``module-attribute` ### `DOCS = _DocsGetter()``module-attribute` ### `ALLUSER_PROGRAMDATA = os.getenv('programdata')``module-attribute` ### `USER_ROAMING_DIR = os.getenv('appdata')``module-attribute` ### `USER_SYS_TEMP = os.getenv('temp')``module-attribute` ### `USER_DESKTOP = op.expandvars('%userprofile%\\desktop')``module-attribute` ### `EXTENSIONS_DEFAULT_DIR = op.join(HOME_DIR, 'extensions')``module-attribute` ### `THIRDPARTY_EXTENSIONS_DEFAULT_DIR = op.join(USER_ROAMING_DIR, PYREVIT_ADDON_NAME, 'Extensions')``module-attribute` ### `PYREVIT_ALLUSER_APP_DIR = op.join(ALLUSER_PROGRAMDATA, PYREVIT_ADDON_NAME)``module-attribute` ### `PYREVIT_APP_DIR = op.join(USER_ROAMING_DIR, PYREVIT_ADDON_NAME)``module-attribute` ### `PYREVIT_VERSION_APP_DIR = op.join(PYREVIT_APP_DIR, HOST_APP.version)``module-attribute` ### `PYREVIT_FILE_PREFIX_UNIVERSAL = '{}_'.format(PYREVIT_ADDON_NAME)``module-attribute` ### `PYREVIT_FILE_PREFIX_UNIVERSAL_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P.+)'``module-attribute` ### `PYREVIT_FILE_PREFIX = '{}_{}_'.format(PYREVIT_ADDON_NAME, HOST_APP.version)``module-attribute` ### `PYREVIT_FILE_PREFIX_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P\\d{4})_(?P.+)'``module-attribute` ### `PYREVIT_FILE_PREFIX_STAMPED = '{}_{}_{}_'.format(PYREVIT_ADDON_NAME, HOST_APP.version, HOST_APP.proc_id)``module-attribute` ### `PYREVIT_FILE_PREFIX_STAMPED_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P\\d{4})_(?P\\d+)_(?P.+)'``module-attribute` ### `PYREVIT_FILE_PREFIX_UNIVERSAL_USER = '{}_{}_'.format(PYREVIT_ADDON_NAME, HOST_APP.username)``module-attribute` ### `PYREVIT_FILE_PREFIX_UNIVERSAL_USER_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P.+)_(?P.+)'``module-attribute` ### `PYREVIT_FILE_PREFIX_USER = '{}_{}_{}_'.format(PYREVIT_ADDON_NAME, HOST_APP.version, HOST_APP.username)``module-attribute` ### `PYREVIT_FILE_PREFIX_USER_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P\\d{4})_(?P.+)_(?P.+)'``module-attribute` ### `PYREVIT_FILE_PREFIX_STAMPED_USER = '{}_{}_{}_{}_'.format(PYREVIT_ADDON_NAME, HOST_APP.version, HOST_APP.username, HOST_APP.proc_id)``module-attribute` ### `PYREVIT_FILE_PREFIX_STAMPED_USER_REGEX = '^' + PYREVIT_ADDON_NAME + '_(?P\\d{4})_(?P.+)_(?P\\d+)_(?P.+)'``module-attribute` ## Classes ### `PyRevitException` Bases: `Exception` Common base class for all pyRevit exceptions. Parameters args and message are derived from Exception class. #### Attributes ##### `msg``property` Return exception message. ### `PyRevitIOError` Bases: `PyRevitException` Common base class for all pyRevit io-related exceptions. #### Attributes ##### `msg``property` Return exception message. ### `PyRevitCPythonNotSupported(feature_name)` Bases: `PyRevitException` Exception for features not supported under CPython. Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
153
154
155
``` | ```md-code__content
def __init__(self, feature_name):
super(PyRevitCPythonNotSupported, self).__init__()
self.feature_name = feature_name
``` | #### Attributes ##### `feature_name = feature_name``instance-attribute` ##### `msg``property` Return exception message. ### `_HostApplication()` Bases: `object` Private Wrapper for Current Instance of Revit. Provides version info and comparison functionality, alongside providing info on the active screen, active document and ui-document, available postable commands, and other functionality. Examples: ```md-code__content hostapp = _HostApplication() hostapp.is_newer_than(2017) ``` Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
197
198
``` | ```md-code__content
def __init__(self):
self._postable_cmds = []
``` | #### Attributes ##### `uiapp``property` Return UIApplication provided to the running command. ##### `app``property` Return Application provided to the running command. ##### `addin_id``property` Return active addin id. ##### `has_api_context``property` Determine if host application is in API context. ##### `uidoc``property` Return active UIDocument. ##### `doc``property` Return active Document. ##### `active_view``property``writable` Return view that is active (UIDocument.ActiveView). ##### `docs``property` Return :obj: `list` of open :obj: `Document` objects. ##### `available_servers``property` Return :obj: `list` of available Revit server names. ##### `version``property` str: Return version number (e.g. '2018'). ##### `subversion``property` str: Return subversion number (e.g. '2018.3'). ##### `version_name``property` str: Return version name (e.g. 'Autodesk Revit 2018'). ##### `build``property` str: Return build number (e.g. '20170927\_1515(x64)'). ##### `serial_no``property` str: Return serial number number (e.g. '569-09704828'). ##### `pretty_name``property` Returns the pretty name of the host. Examples: Autodesk Revit 2019.2 build: 20190808\_0900(x64) Returns: | Type | Description | | --- | --- | | `str` | Pretty name of the host | ##### `is_demo``property` bool: Determine if product is using demo license. ##### `language``property` str: Return language type (e.g. 'LanguageType.English\_USA'). ##### `username``property` str: Return the username from Revit API (Application.Username). ##### `proc``property` System.Diagnostics.Process: Return current process object. ##### `proc_id``property` int: Return current process id. ##### `proc_name``property` str: Return current process name. ##### `proc_path``property` str: Return file path for the current process main module. ##### `proc_window``property` `intptr`: Return handle to current process window. ##### `proc_screen``property` `intptr`: Return handle to screen hosting current process. ##### `proc_screen_workarea``property` `System.Drawing.Rectangle`: Return screen working area. ##### `proc_screen_scalefactor``property` float: Return scaling for screen hosting current process. #### Functions ##### `is_newer_than(version, or_equal=False)` bool: Return True if host app is newer than provided version. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `version` | `str or int` | version to check against. | _required_ | | `or_equal` | `bool` | Whether to include `version` in the comparison | `False` | Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
369
370
371
372
373
374
375
376
377
378
379
``` | ```md-code__content
def is_newer_than(self, version, or_equal=False):
"""bool: Return True if host app is newer than provided version.
Args:
version (str or int): version to check against.
or_equal (bool): Whether to include `version` in the comparison
"""
if or_equal:
return int(self.version) >= int(version)
else:
return int(self.version) > int(version)
``` | ##### `is_older_than(version)` bool: Return True if host app is older than provided version. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `version` | `str or int` | version to check against. | _required_ | Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
381
382
383
384
385
386
387
``` | ```md-code__content
def is_older_than(self, version):
"""bool: Return True if host app is older than provided version.
Args:
version (str or int): version to check against.
"""
return int(self.version) < int(version)
``` | ##### `is_exactly(version)` bool: Return True if host app is equal to provided version. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `version` | `str or int` | version to check against. | _required_ | Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
389
390
391
392
393
394
395
``` | ```md-code__content
def is_exactly(self, version):
"""bool: Return True if host app is equal to provided version.
Args:
version (str or int): version to check against.
"""
return int(self.version) == int(version)
``` | ##### `get_postable_commands()` Return list of postable commands. Returns: | Type | Description | | --- | --- | | `list[_HostAppPostableCommand]` | postable commands. | Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
``` | ```md-code__content
def get_postable_commands(self):
"""Return list of postable commands.
Returns:
(list[_HostAppPostableCommand]): postable commands.
"""
# if list of postable commands is _not_ already created
# make the list and store in instance parameter
if not self._postable_cmds:
for pc in UI.PostableCommand.GetValues(UI.PostableCommand):
try:
rcid = UI.RevitCommandId.LookupPostableCommandId(pc)
self._postable_cmds.append(
# wrap postable command info in custom namedtuple
_HostAppPostableCommand(name=safe_strtype(pc),
key=rcid.Name,
id=rcid.Id,
rvtobj=rcid)
)
except Exception:
# if any error occured when querying postable command
# or its info, pass silently
pass
return self._postable_cmds
``` | ##### `post_command(command_id)` Request Revit to run a command. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `command_id` | `str` | command identifier e.g. ID\_REVIT\_SAVE\_AS\_TEMPLATE | _required_ | Source code in `pyrevitlib/pyrevit/__init__.py` | | | | --- | --- | | ```
423
424
425
426
427
428
429
430
``` | ```md-code__content
def post_command(self, command_id):
"""Request Revit to run a command.
Args:
command_id (str): command identifier e.g. ID_REVIT_SAVE_AS_TEMPLATE
"""
command_id = UI.RevitCommandId.LookupCommandId(command_id)
self.uiapp.PostCommand(command_id)
``` | Back to top ## PyRevit Extensions Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/#pyrevit.extensions) # extensions Base module for handling extensions parsing. ## Attributes ### `LIB_EXTENSION_POSTFIX = '.lib'``module-attribute` ### `UI_EXTENSION_POSTFIX = '.extension'``module-attribute` ### `PYTHON_LANG = 'python'``module-attribute` ### `CSHARP_LANG = 'csharp'``module-attribute` ### `VB_LANG = 'visualbasic'``module-attribute` ### `RUBY_LANG = 'ruby'``module-attribute` ### `DYNAMO_LANG = 'dynamobim'``module-attribute` ### `GRASSHOPPER_LANG = 'grasshopper'``module-attribute` ### `CPYTHON_HASHBANG = '\#! python3'``module-attribute` ### `PYTHON_SCRIPT_FILE_FORMAT = '.py'``module-attribute` ### `CSHARP_SCRIPT_FILE_FORMAT = '.cs'``module-attribute` ### `VB_SCRIPT_FILE_FORMAT = '.vb'``module-attribute` ### `RUBY_SCRIPT_FILE_FORMAT = '.rb'``module-attribute` ### `DYNAMO_SCRIPT_FILE_FORMAT = '.dyn'``module-attribute` ### `GRASSHOPPER_SCRIPT_FILE_FORMAT = '.gh'``module-attribute` ### `GRASSHOPPERX_SCRIPT_FILE_FORMAT = '.ghx'``module-attribute` ### `CONTENT_FILE_FORMAT = '.rfa'``module-attribute` ### `EXT_STARTUP_NAME = 'startup'``module-attribute` ### `PYTHON_EXT_STARTUP_FILE = EXT_STARTUP_NAME + PYTHON_SCRIPT_FILE_FORMAT``module-attribute` ### `CSHARP_EXT_STARTUP_FILE = EXT_STARTUP_NAME + CSHARP_SCRIPT_FILE_FORMAT``module-attribute` ### `VB_EXT_STARTUP_FILE = EXT_STARTUP_NAME + VB_SCRIPT_FILE_FORMAT``module-attribute` ### `RUBY_EXT_STARTUP_FILE = EXT_STARTUP_NAME + RUBY_SCRIPT_FILE_FORMAT``module-attribute` ### `YAML_FILE_FORMAT = '.yaml'``module-attribute` ### `JSON_FILE_FORMAT = '.json'``module-attribute` ### `EXT_MANIFEST_NAME = 'extension'``module-attribute` ### `EXT_MANIFEST_FILE = EXT_MANIFEST_NAME + JSON_FILE_FORMAT``module-attribute` ### `DEFAULT_BUNDLEMATA_NAME = 'bundle'``module-attribute` ### `BUNDLEMATA_POSTFIX = DEFAULT_BUNDLEMATA_NAME + YAML_FILE_FORMAT``module-attribute` ### `MDATA_UI_TITLE = 'title'``module-attribute` ### `MDATA_TOOLTIP = 'tooltip'``module-attribute` ### `MDATA_AUTHOR = 'author'``module-attribute` ### `MDATA_AUTHORS = 'authors'``module-attribute` ### `MDATA_LAYOUT = 'layout'``module-attribute` ### `MDATA_COMMAND_HELP_URL = 'help_url'``module-attribute` ### `MDATA_COMMAND_CONTEXT = 'context'``module-attribute` ### `MDATA_COMMAND_CONTEXT_TYPE = 'type'``module-attribute` ### `MDATA_COMMAND_CONTEXT_NOT = 'not_'``module-attribute` ### `MDATA_COMMAND_CONTEXT_ANY = 'any'``module-attribute` ### `MDATA_COMMAND_CONTEXT_ALL = 'all'``module-attribute` ### `MDATA_COMMAND_CONTEXT_EXACT = 'exact'``module-attribute` ### `MDATA_COMMAND_CONTEXT_NOTANY = MDATA_COMMAND_CONTEXT_NOT + MDATA_COMMAND_CONTEXT_ANY``module-attribute` ### `MDATA_COMMAND_CONTEXT_NOTALL = MDATA_COMMAND_CONTEXT_NOT + MDATA_COMMAND_CONTEXT_ALL``module-attribute` ### `MDATA_COMMAND_CONTEXT_NOTEXACT = MDATA_COMMAND_CONTEXT_NOT + MDATA_COMMAND_CONTEXT_EXACT``module-attribute` ### `MDATA_COMMAND_CONTEXT_ANY_SEP = '|'``module-attribute` ### `MDATA_COMMAND_CONTEXT_ALL_SEP = '&'``module-attribute` ### `MDATA_COMMAND_CONTEXT_EXACT_SEP = ';'``module-attribute` ### `MDATA_COMMAND_CONTEXT_RULE = '({rule})'``module-attribute` ### `MDATA_MIN_REVIT_VERSION = 'min_revit_version'``module-attribute` ### `MDATA_MAX_REVIT_VERSION = 'max_revit_version'``module-attribute` ### `MDATA_BETA_SCRIPT = 'is_beta'``module-attribute` ### `MDATA_ENGINE = 'engine'``module-attribute` ### `MDATA_ENGINE_CLEAN = 'clean'``module-attribute` ### `MDATA_ENGINE_FULLFRAME = 'full_frame'``module-attribute` ### `MDATA_ENGINE_PERSISTENT = 'persistent'``module-attribute` ### `MDATA_ENGINE_MAINTHREAD = 'mainthread'``module-attribute` ### `MDATA_LINK_BUTTON_MODULES = 'modules'``module-attribute` ### `MDATA_LINK_BUTTON_ASSEMBLY = 'assembly'``module-attribute` ### `MDATA_LINK_BUTTON_COMMAND_CLASS = 'command_class'``module-attribute` ### `MDATA_LINK_BUTTON_AVAIL_COMMAND_CLASS = 'availability_class'``module-attribute` ### `MDATA_URL_BUTTON_HYPERLINK = 'hyperlink'``module-attribute` ### `MDATA_TEMPLATES_KEY = 'templates'``module-attribute` ### `MDATA_BACKGROUND_KEY = 'background'``module-attribute` ### `MDATA_BACKGROUND_PANEL_KEY = 'panel'``module-attribute` ### `MDATA_BACKGROUND_TITLE_KEY = 'title'``module-attribute` ### `MDATA_BACKGROUND_SLIDEOUT_KEY = 'slideout'``module-attribute` ### `MDATA_HIGHLIGHT_KEY = 'highlight'``module-attribute` ### `MDATA_HIGHLIGHT_TYPE_NEW = 'new'``module-attribute` ### `MDATA_HIGHLIGHT_TYPE_UPDATED = 'updated'``module-attribute` ### `MDATA_COLLAPSED_KEY = 'collapsed'``module-attribute` ### `MDATA_ENGINE_DYNAMO_AUTOMATE = 'automate'``module-attribute` ### `MDATA_ENGINE_DYNAMO_PATH = 'dynamo_path'``module-attribute` ### `MDATA_ENGINE_DYNAMO_PATH_CHECK_EXIST = 'dynamo_path_check_existing'``module-attribute` ### `MDATA_ENGINE_DYNAMO_FORCE_MANUAL_RUN = 'dynamo_force_manual_run'``module-attribute` ### `MDATA_ENGINE_DYNAMO_MODEL_NODES_INFO = 'dynamo_model_nodes_info'``module-attribute` ### `UI_TITLE_PARAM = '__title__'``module-attribute` ### `DOCSTRING_PARAM = '__doc__'``module-attribute` ### `AUTHOR_PARAM = '__author__'``module-attribute` ### `AUTHORS_PARAM = '__authors__'``module-attribute` ### `COMMAND_HELP_URL_PARAM = '__helpurl__'``module-attribute` ### `COMMAND_CONTEXT_PARAM = '__context__'``module-attribute` ### `MIN_REVIT_VERSION_PARAM = '__min_revit_ver__'``module-attribute` ### `MAX_REVIT_VERSION_PARAM = '__max_revit_ver__'``module-attribute` ### `SHIFT_CLICK_PARAM = '__shiftclick__'``module-attribute` ### `BETA_SCRIPT_PARAM = '__beta__'``module-attribute` ### `HIGHLIGHT_SCRIPT_PARAM = '__highlight__'``module-attribute` ### `CLEAN_ENGINE_SCRIPT_PARAM = '__cleanengine__'``module-attribute` ### `FULLFRAME_ENGINE_PARAM = '__fullframeengine__'``module-attribute` ### `PERSISTENT_ENGINE_PARAM = '__persistentengine__'``module-attribute` ### `TAB_POSTFIX = '.tab'``module-attribute` ### `PANEL_POSTFIX = '.panel'``module-attribute` ### `LINK_BUTTON_POSTFIX = '.linkbutton'``module-attribute` ### `INVOKE_BUTTON_POSTFIX = '.invokebutton'``module-attribute` ### `PUSH_BUTTON_POSTFIX = '.pushbutton'``module-attribute` ### `SMART_BUTTON_POSTFIX = '.smartbutton'``module-attribute` ### `PULLDOWN_BUTTON_POSTFIX = '.pulldown'``module-attribute` ### `STACK_BUTTON_POSTFIX = '.stack'``module-attribute` ### `SPLIT_BUTTON_POSTFIX = '.splitbutton'``module-attribute` ### `SPLITPUSH_BUTTON_POSTFIX = '.splitpushbutton'``module-attribute` ### `PANEL_PUSH_BUTTON_POSTFIX = '.panelbutton'``module-attribute` ### `NOGUI_COMMAND_POSTFIX = '.nobutton'``module-attribute` ### `CONTENT_BUTTON_POSTFIX = '.content'``module-attribute` ### `URL_BUTTON_POSTFIX = '.urlbutton'``module-attribute` ### `COMP_LIBRARY_DIR_NAME = 'lib'``module-attribute` ### `COMP_BIN_DIR_NAME = 'bin'``module-attribute` ### `COMP_HOOKS_DIR_NAME = 'hooks'``module-attribute` ### `COMP_CHECKS_DIR_NAME = 'checks'``module-attribute` ### `UNIQUE_ID_SEPARATOR = '-'``module-attribute` ### `SEPARATOR_IDENTIFIER = '---'``module-attribute` ### `SLIDEOUT_IDENTIFIER = '>>>'``module-attribute` ### `ICON_FILE_FORMAT = '.png'``module-attribute` ### `ICON_DARK_SUFFIX = '.dark'``module-attribute` ### `DEFAULT_ICON_FILE = 'icon' + ICON_FILE_FORMAT``module-attribute` ### `DEFAULT_ON_ICON_FILE = 'on' + ICON_FILE_FORMAT``module-attribute` ### `DEFAULT_OFF_ICON_FILE = 'off' + ICON_FILE_FORMAT``module-attribute` ### `DEFAULT_MEDIA_FILENAME = 'tooltip'``module-attribute` ### `DEFAULT_SCRIPT_NAME = 'script'``module-attribute` ### `DEFAULT_CONFIG_NAME = 'config'``module-attribute` ### `PYTHON_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + PYTHON_SCRIPT_FILE_FORMAT``module-attribute` ### `PYTHON_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + PYTHON_SCRIPT_FILE_FORMAT``module-attribute` ### `CSHARP_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + CSHARP_SCRIPT_FILE_FORMAT``module-attribute` ### `CSHARP_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + CSHARP_SCRIPT_FILE_FORMAT``module-attribute` ### `VB_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + VB_SCRIPT_FILE_FORMAT``module-attribute` ### `VB_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + VB_SCRIPT_FILE_FORMAT``module-attribute` ### `RUBY_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + RUBY_SCRIPT_FILE_FORMAT``module-attribute` ### `RUBY_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + RUBY_SCRIPT_FILE_FORMAT``module-attribute` ### `DYNAMO_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + DYNAMO_SCRIPT_FILE_FORMAT``module-attribute` ### `DYNAMO_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + DYNAMO_SCRIPT_FILE_FORMAT``module-attribute` ### `GRASSHOPPER_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + GRASSHOPPER_SCRIPT_FILE_FORMAT``module-attribute` ### `GRASSHOPPER_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + GRASSHOPPER_SCRIPT_FILE_FORMAT``module-attribute` ### `GRASSHOPPERX_SCRIPT_POSTFIX = DEFAULT_SCRIPT_NAME + GRASSHOPPERX_SCRIPT_FILE_FORMAT``module-attribute` ### `GRASSHOPPERX_CONFIG_SCRIPT_POSTFIX = DEFAULT_CONFIG_NAME + GRASSHOPPERX_SCRIPT_FILE_FORMAT``module-attribute` ### `DEFAULT_CONTENT_NAME = 'content'``module-attribute` ### `DEFAULT_ALT_CONTENT_NAME = 'other'``module-attribute` ### `CONTENT_POSTFIX = DEFAULT_CONTENT_NAME + CONTENT_FILE_FORMAT``module-attribute` ### `CONTENT_VERSION_POSTFIX = DEFAULT_CONTENT_NAME + '_{version}' + CONTENT_FILE_FORMAT``module-attribute` ### `ALT_CONTENT_POSTFIX = DEFAULT_ALT_CONTENT_NAME + CONTENT_FILE_FORMAT``module-attribute` ### `ALT_CONTENT_VERSION_POSTFIX = DEFAULT_ALT_CONTENT_NAME + '_{version}' + CONTENT_FILE_FORMAT``module-attribute` ### `HELP_FILE_PATTERN = '.*help\\..+'``module-attribute` ### `CTX_SELETION = 'selection'``module-attribute` ### `CTX_ZERODOC = 'zero-doc'``module-attribute` ## Classes ### `UIExtensionType` UI extension type. #### Attributes ##### `ID = 'extension'``class-attribute``instance-attribute` ##### `POSTFIX = '.extension'``class-attribute``instance-attribute` ### `LIBExtensionType` Library extension type. #### Attributes ##### `ID = 'lib'``class-attribute``instance-attribute` ##### `POSTFIX = '.lib'``class-attribute``instance-attribute` ### `ExtensionTypes` Extension types. #### Attributes ##### `UI_EXTENSION = UIExtensionType``class-attribute``instance-attribute` ##### `LIB_EXTENSION = LIBExtensionType``class-attribute``instance-attribute` #### Functions ##### `get_ext_types()``classmethod` Source code in `pyrevitlib/pyrevit/extensions/__init__.py` | | | | --- | --- | | ```
27
28
29
30
31
32
33
``` | ```md-code__content
@classmethod
def get_ext_types(cls):
ext_types = set()
for attr in dir(cls):
if attr.endswith('_EXTENSION'):
ext_types.add(getattr(cls, attr))
return ext_types
``` | Back to top ## Revit API Reference [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/api/#pyrevit.api) # api Provide access to Revit API. Examples: ```md-code__content from pyrevit.api import AdWindows ``` ## Functions ### `get_product_serial_number()` Return serial number of running host instance. Returns: | Type | Description | | --- | --- | | `str` | Serial number | Source code in `pyrevitlib/pyrevit/api.py` | | | | --- | --- | | ```
34
35
36
37
38
39
40
``` | ```md-code__content
def get_product_serial_number():
"""Return serial number of running host instance.
Returns:
(str): Serial number
"""
return UIFrameworkServices.InfoCenterService.ProductSerialNumber
``` | ### `is_product_demo()` Determine if product is using demo license. Returns: | Type | Description | | --- | --- | | `bool` | True if product is using demo license | Source code in `pyrevitlib/pyrevit/api.py` | | | | --- | --- | | ```
43
44
45
46
47
48
49
``` | ```md-code__content
def is_product_demo():
"""Determine if product is using demo license.
Returns:
(bool): True if product is using demo license
"""
return get_product_serial_number() == '000-00000000'
``` | ### `is_api_object(data_type)` Check if given object belongs to Revit API. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `data_type` | `object` | Object to check | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if object belongs to Revit API | Source code in `pyrevitlib/pyrevit/api.py` | | | | --- | --- | | ```
52
53
54
55
56
57
58
59
60
61
62
``` | ```md-code__content
def is_api_object(data_type):
"""Check if given object belongs to Revit API.
Args:
data_type (object): Object to check
Returns:
(bool): True if object belongs to Revit API
"""
if hasattr(data_type, 'GetType'):
return 'Autodesk.Revit.' in data_type.GetType().Namespace
``` | Back to top ## DotNet Framework Access [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/framework/#pyrevit.framework) # framework Provide access to DotNet Framework. Examples: ```md-code__content from pyrevit.framework import Assembly, Windows ``` ## Attributes ### `ASSEMBLY_FILE_TYPE = 'dll'``module-attribute` ### `ASSEMBLY_FILE_EXT = '.dll'``module-attribute` ### `ipy_assmname = '{prefix}IronPython'.format(prefix=eng.EnginePrefix)``module-attribute` ### `ipy_dllpath = op.join(eng.EnginePath, ipy_assmname + ASSEMBLY_FILE_EXT)``module-attribute` ### `wpf_assmname = '{prefix}IronPython.Wpf'.format(prefix=eng.EnginePrefix)``module-attribute` ### `wpf_dllpath = op.join(eng.EnginePath, wpf_assmname + ASSEMBLY_FILE_EXT)``module-attribute` ### `sqlite3_assmname = '{prefix}IronPython.SQLite'.format(prefix=eng.EnginePrefix)``module-attribute` ### `sqlite3_dllpath = op.join(eng.EnginePath, sqlite3_assmname + ASSEMBLY_FILE_EXT)``module-attribute` ## Functions ### `get_type(fw_object)` Return CLR type of an object. Source code in `pyrevitlib/pyrevit/framework.py` | | | | --- | --- | | ```
156
157
158
``` | ```md-code__content
def get_type(fw_object):
"""Return CLR type of an object."""
return clr.GetClrType(fw_object)
``` | ### `get_dll_file(assembly_name)` Return path to given assembly name. Source code in `pyrevitlib/pyrevit/framework.py` | | | | --- | --- | | ```
161
162
163
164
165
``` | ```md-code__content
def get_dll_file(assembly_name):
"""Return path to given assembly name."""
addin_file = op.join(BIN_DIR, assembly_name + '.dll')
if op.exists(addin_file):
return addin_file
``` | ### `get_current_thread_id()` Return manageed thread id of current thread. Source code in `pyrevitlib/pyrevit/framework.py` | | | | --- | --- | | ```
168
169
170
``` | ```md-code__content
def get_current_thread_id():
"""Return manageed thread id of current thread."""
return System.Threading.Thread.CurrentThread.ManagedThreadId
``` | Back to top ## pyRevit Version Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/versionmgr/#pyrevit.versionmgr) # versionmgr Utility functions for managing pyRevit versions. Examples: ```md-code__content from pyrevit import versionmgr v = versionmgr.get_pyrevit_version() v.get_formatted() ``` '4.10-beta2' ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Functions ### `get_pyrevit_repo()` Return pyRevit repository. Returns: | Type | Description | | --- | --- | | `RepoInfo` | repo wrapper object | Source code in `pyrevitlib/pyrevit/versionmgr/__init__.py` | | | | --- | --- | | ```
74
75
76
77
78
79
80
81
82
83
84
``` | ```md-code__content
def get_pyrevit_repo():
"""Return pyRevit repository.
Returns:
(pyrevit.coreutils.git.RepoInfo): repo wrapper object
"""
try:
return git.get_repo(HOME_DIR)
except Exception as repo_err:
mlogger.debug('Can not create repo from directory: %s | %s',
HOME_DIR, repo_err)
``` | ### `get_pyrevit_version()` Return information about active pyRevit version. Returns: | Type | Description | | --- | --- | | `_PyRevitVersion` | version wrapper object | Source code in `pyrevitlib/pyrevit/versionmgr/__init__.py` | | | | --- | --- | | ```
87
88
89
90
91
92
93
94
95
96
97
``` | ```md-code__content
def get_pyrevit_version():
"""Return information about active pyRevit version.
Returns:
(_PyRevitVersion): version wrapper object
"""
try:
return _PyRevitVersion(get_pyrevit_repo().last_commit_hash)
except Exception as ver_err:
mlogger.debug('Can not get pyRevit patch number. | %s', ver_err)
return _PyRevitVersion('')
``` | ### `get_pyrevit_cli_version()` Return version of shipped pyRevit CLI utility. Returns: | Type | Description | | --- | --- | | `str` | version string of pyRevit CLI utility binary | Source code in `pyrevitlib/pyrevit/versionmgr/__init__.py` | | | | --- | --- | | ```
100
101
102
103
104
105
106
``` | ```md-code__content
def get_pyrevit_cli_version():
"""Return version of shipped pyRevit CLI utility.
Returns:
(str): version string of pyRevit CLI utility binary
"""
return coreutils.get_exe_version(PYREVIT_CLI_PATH)
``` | Back to top ## Python Compatibility Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/compat/#pyrevit.compat) # compat python engine compatibility module. Examples: ```md-code__content from pyrevit.compat import IRONPY2711 from pyrevit.compat import safe_strtype ``` ## Attributes ### `PY2 = sys.version_info[0] == 2``module-attribute` ### `PY3 = sys.version_info[0] == 3``module-attribute` ### `IRONPY = '.net' in sys.version.lower()``module-attribute` ### `IRONPY2 = PY2 and IRONPY``module-attribute` ### `IRONPY3 = PY3 and IRONPY``module-attribute` ### `NETCORE = System.Environment.Version.Major >= 8``module-attribute` ### `NETFRAMEWORK = not NETCORE``module-attribute` ### `NO_REVIT = -1``module-attribute` ### `REVIT_NETCORE_VERSION = 2025``module-attribute` ### `safe_strtype = str``module-attribute` ## Functions ### `get_elementid_value_func()` Returns the ElementId value extraction function based on the Revit version. Follows API changes in Revit 2024. Returns: | Name | Type | Description | | --- | --- | --- | | `function` | | A function returns the value of an ElementId. | Examples: ```md-code__content get_elementid_value = get_elementid_value_func() sheet_revids = {get_elementid_value(x) for x in self.revit_sheet.GetAllRevisionIds()} add_sheet_revids = {get_elementid_value(x) x in self.revit_sheet.GetAdditionalRevisionIds()} ``` Source code in `pyrevitlib/pyrevit/compat.py` | | | | --- | --- | | ```
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
``` | ````md-code__content
def get_elementid_value_func():
"""Returns the ElementId value extraction function based on the Revit version.
Follows API changes in Revit 2024.
Returns:
function: A function returns the value of an ElementId.
Examples:
```python
get_elementid_value = get_elementid_value_func()
sheet_revids = {get_elementid_value(x) for x in self.revit_sheet.GetAllRevisionIds()}
add_sheet_revids = {get_elementid_value(x) x in self.revit_sheet.GetAdditionalRevisionIds()}
```
"""
def get_value_post2024(item):
return item.Value
def get_value_pre2024(item):
return item.IntegerValue
return get_value_post2024 if _get_revit_version() > 2023 else get_value_pre2024
```` | ### `urlopen(url)` Urlopen wrapper. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `url` | `str` | request url | _required_ | Source code in `pyrevitlib/pyrevit/compat.py` | | | | --- | --- | | ```
90
91
92
93
94
95
96
97
98
``` | ```md-code__content
def urlopen(url):
"""Urlopen wrapper.
Args:
url (str): request url
"""
if PY3:
return urllib.request.urlopen(url)
return urllib2.urlopen(url)
``` | ### `make_request(url, headers, data)` Urlopen wrapper to create and send a request. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `url` | `str` | request url | _required_ | | `headers` | `dict[str, str]` | headers | _required_ | | `data` | `bytes | None` | request data | _required_ | Source code in `pyrevitlib/pyrevit/compat.py` | | | | --- | --- | | ```
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
``` | ```md-code__content
def make_request(url, headers, data):
"""Urlopen wrapper to create and send a request.
Args:
url (str): request url
headers (dict[str, str]): headers
data (bytes | None): request data
"""
if PY3:
req = urllib.request.Request(url, headers, data)
urllib.request.urlopen(req).close()
return
req = urllib2.Request(url, headers, data)
urllib2.urlopen(req).close()
``` | Back to top ## pyRevit Telemetry [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/telemetry/#pyrevit.telemetry) # telemetry This module manages the telemetry system. This function is used to setup the telemetry system on pyRevit startup ```md-code__content setup_telemetry() ``` These functions are used to query information about the logging system ```md-code__content get_telemetry_state() ``` ```md-code__content get_apptelemetry_state() ``` This module also provides a wrapper class around the command results dictionary that is included with the telemetry record. Scripts should use the instance of this class provided by the script module. See `script.get_results()` for examples ## Attributes ### `FILE_LOG_EXT = 'json'``module-attribute` ### `FILE_LOG_FILENAME_TEMPLATE = '{}_{}_telemetry.{}'``module-attribute` ### `mlogger = get_logger(__name__)``module-attribute` ### `consts = PyRevit.PyRevitConsts``module-attribute` ## Functions ### `get_default_telemetry_filepath()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
53
54
``` | ```md-code__content
def get_default_telemetry_filepath():
return PYREVIT_VERSION_APP_DIR
``` | ### `get_telemetry_state()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
57
58
``` | ```md-code__content
def get_telemetry_state():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYSTATE_ENVVAR)
``` | ### `get_telemetry_utc_timestamp()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
61
62
``` | ```md-code__content
def get_telemetry_utc_timestamp():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYUTCTIMESTAMPS_ENVVAR)
``` | ### `get_telemetry_file_dir()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
65
66
``` | ```md-code__content
def get_telemetry_file_dir():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYDIR_ENVVAR)
``` | ### `get_telemetry_file_path()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
69
70
``` | ```md-code__content
def get_telemetry_file_path():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYFILE_ENVVAR)
``` | ### `get_telemetry_server_url()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
73
74
``` | ```md-code__content
def get_telemetry_server_url():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYSERVER_ENVVAR)
``` | ### `get_telemetry_include_hooks()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
77
78
``` | ```md-code__content
def get_telemetry_include_hooks():
return envvars.get_pyrevit_env_var(envvars.TELEMETRYINCLUDEHOOKS_ENVVAR)
``` | ### `set_telemetry_state(state)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
81
82
83
``` | ```md-code__content
def set_telemetry_state(state):
envvars.set_pyrevit_env_var(envvars.TELEMETRYSTATE_ENVVAR, state)
user_config.telemetry_status = state
``` | ### `set_telemetry_utc_timestamp(state)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
86
87
88
``` | ```md-code__content
def set_telemetry_utc_timestamp(state):
envvars.set_pyrevit_env_var(envvars.TELEMETRYUTCTIMESTAMPS_ENVVAR, state)
user_config.telemetry_utc_timestamp = state
``` | ### `set_telemetry_file_dir(file_dir)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
91
92
93
94
95
``` | ```md-code__content
def set_telemetry_file_dir(file_dir):
if not file_dir or not op.isdir(file_dir):
disable_telemetry_to_file()
envvars.set_pyrevit_env_var(envvars.TELEMETRYDIR_ENVVAR, file_dir)
user_config.telemetry_file_dir = file_dir
``` | ### `set_telemetry_file_path(file_path)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
98
99
``` | ```md-code__content
def set_telemetry_file_path(file_path):
envvars.set_pyrevit_env_var(envvars.TELEMETRYFILE_ENVVAR, file_path)
``` | ### `set_telemetry_server_url(server_url)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
102
103
104
``` | ```md-code__content
def set_telemetry_server_url(server_url):
envvars.set_pyrevit_env_var(envvars.TELEMETRYSERVER_ENVVAR, server_url)
user_config.telemetry_server_url = server_url
``` | ### `set_telemetry_include_hooks(state)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
107
108
109
``` | ```md-code__content
def set_telemetry_include_hooks(state):
envvars.set_pyrevit_env_var(envvars.TELEMETRYINCLUDEHOOKS_ENVVAR, state)
user_config.telemetry_include_hooks = state
``` | ### `disable_telemetry()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
112
113
``` | ```md-code__content
def disable_telemetry():
set_telemetry_state(False)
``` | ### `disable_telemetry_to_file()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
116
117
``` | ```md-code__content
def disable_telemetry_to_file():
set_telemetry_file_path('')
``` | ### `disable_telemetry_to_server()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
120
121
``` | ```md-code__content
def disable_telemetry_to_server():
set_telemetry_server_url('')
``` | ### `get_apptelemetry_state()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
124
125
``` | ```md-code__content
def get_apptelemetry_state():
return envvars.get_pyrevit_env_var(envvars.APPTELEMETRYSTATE_ENVVAR)
``` | ### `set_apptelemetry_state(state)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
128
129
130
``` | ```md-code__content
def set_apptelemetry_state(state):
envvars.set_pyrevit_env_var(envvars.APPTELEMETRYSTATE_ENVVAR, state)
user_config.apptelemetry_status = state
``` | ### `get_apptelemetry_handler()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
133
134
``` | ```md-code__content
def get_apptelemetry_handler():
return envvars.get_pyrevit_env_var(envvars.APPTELEMETRYHANDLER_ENVVAR)
``` | ### `set_apptelemetry_handler(handler)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
137
138
``` | ```md-code__content
def set_apptelemetry_handler(handler):
envvars.set_pyrevit_env_var(envvars.APPTELEMETRYHANDLER_ENVVAR, handler)
``` | ### `get_apptelemetry_server_url()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
141
142
``` | ```md-code__content
def get_apptelemetry_server_url():
return envvars.get_pyrevit_env_var(envvars.APPTELEMETRYSERVER_ENVVAR)
``` | ### `get_apptelemetry_event_flags()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
145
146
147
148
149
``` | ```md-code__content
def get_apptelemetry_event_flags():
# default value is 16 bytes of 0
flags_hex = \
user_config.apptelemetry_event_flags or '0x00000000000000000000000000000000'
return coreutils.hex2int_long(flags_hex)
``` | ### `set_apptelemetry_server_url(server_url)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
152
153
154
``` | ```md-code__content
def set_apptelemetry_server_url(server_url):
envvars.set_pyrevit_env_var(envvars.APPTELEMETRYSERVER_ENVVAR, server_url)
user_config.apptelemetry_server_url = server_url
``` | ### `set_apptelemetry_event_flags(event_flags)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
157
158
159
160
161
``` | ```md-code__content
def set_apptelemetry_event_flags(event_flags):
flags_hex = coreutils.int2hex_long(event_flags)
user_config.apptelemetry_event_flags = flags_hex
envvars.set_pyrevit_env_var(
envvars.APPTELEMETRYEVENTFLAGS_ENVVAR, flags_hex)
``` | ### `disable_apptelemetry()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
164
165
``` | ```md-code__content
def disable_apptelemetry():
set_apptelemetry_state(False)
``` | ### `disable_apptelemetry_to_server()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
168
169
``` | ```md-code__content
def disable_apptelemetry_to_server():
set_apptelemetry_server_url('')
``` | ### `get_apptelemetry_event_types()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
172
173
``` | ```md-code__content
def get_apptelemetry_event_types():
return list(coreutils.get_enum_values(EventType))
``` | ### `get_apptelemetry_event_state(flags, event_type)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
176
177
178
``` | ```md-code__content
def get_apptelemetry_event_state(flags, event_type):
event_idx = get_apptelemetry_event_types().index(event_type)
return flags & (1<``` | ### `set_apptelemetry_event_state(flags, event_type)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
181
182
``` | ```md-code__content
def set_apptelemetry_event_state(flags, event_type):
return flags | (1<``` | ### `unset_apptelemetry_event_state(flags, event_type)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
185
186
``` | ```md-code__content
def unset_apptelemetry_event_state(flags, event_type):
return flags & ~(1<``` | ### `get_status_from_url(server_url)` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
197
198
199
200
201
202
203
204
205
206
207
``` | ```md-code__content
def get_status_from_url(server_url):
server_url = server_url.lower()
if server_url.endswith('scripts/'):
server_url = server_url.replace('scripts/', 'status')
elif server_url.endswith('events/'):
server_url = server_url.replace('events/', 'status')
try:
return json.loads(urlopen(server_url).read())
except Exception:
return None
``` | ### `get_status()` Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
210
211
212
213
214
``` | ```md-code__content
def get_status():
return get_status_from_url(
get_telemetry_server_url()
or get_apptelemetry_server_url()
)
``` | ### `setup_telemetry(session_id=None)` Sets up the telemetry default config and environment values. Source code in `pyrevitlib/pyrevit/telemetry/__init__.py` | | | | --- | --- | | ```
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
``` | ```md-code__content
def setup_telemetry(session_id=None):
"""Sets up the telemetry default config and environment values."""
# make sure session id is availabe
if not session_id:
session_id = sessioninfo.get_session_uuid()
# PYREVIT TELEMETRY -------------------------------------------------------
# utc timestamp
telemetry_utc_timestamp = user_config.telemetry_utc_timestamp
set_telemetry_utc_timestamp(telemetry_utc_timestamp)
# global telemetry toggle
telemetry_state = user_config.telemetry_status
set_telemetry_state(telemetry_state)
# read or setup default values for file telemetry
# default file path and name for telemetry
telemetry_file_dir = user_config.telemetry_file_dir
set_telemetry_file_dir(telemetry_file_dir)
# check file telemetry config and setup destination
if not telemetry_file_dir or coreutils.is_blank(telemetry_file_dir):
# if no config is provided, disable output
disable_telemetry_to_file()
# if config exists, create new telemetry file under the same address
elif telemetry_state:
if op.isdir(telemetry_file_dir):
telemetry_file_name = \
FILE_LOG_FILENAME_TEMPLATE.format(PYREVIT_FILE_PREFIX,
session_id,
FILE_LOG_EXT)
# if directory is valid
telemetry_fullfilepath = \
op.join(telemetry_file_dir, telemetry_file_name)
set_telemetry_file_path(telemetry_fullfilepath)
# setup telemetry file or disable if failed
try:
_setup_default_logfile(telemetry_fullfilepath)
except Exception as write_err:
mlogger.error('Telemetry is active but log file location '
'is not accessible. | %s', write_err)
disable_telemetry_to_file()
else:
# if not, show error and disable telemetry
mlogger.error('Provided telemetry address does not exits or is '
'not a directory. Telemetry disabled.')
disable_telemetry_to_file()
# read or setup default values for server telemetry
telemetry_server_url = user_config.telemetry_server_url
# check server telemetry config and setup destination
if not telemetry_server_url or coreutils.is_blank(telemetry_server_url):
# if no config is provided, disable output
disable_telemetry_to_server()
else:
# if config exists, setup server logging
set_telemetry_server_url(telemetry_server_url)
# set telemetry script types
set_telemetry_include_hooks(user_config.telemetry_include_hooks)
# APP TELEMETRY ------------------------------------------------------------
# setup default value for telemetry global switch
apptelemetry_state = user_config.apptelemetry_status
set_apptelemetry_state(apptelemetry_state)
# read or setup default values for server telemetry
apptelemetry_server_url = user_config.apptelemetry_server_url
# check server telemetry config and setup destination
if not apptelemetry_server_url \
or coreutils.is_blank(apptelemetry_server_url):
# if no config is provided, disable output
disable_apptelemetry_to_server()
else:
# if config exists, setup server logging
set_apptelemetry_server_url(apptelemetry_server_url)
# setup events
new_telemetry_handler = EventTelemetry(session_id, HOST_APP.username)
telemetry_handler = get_apptelemetry_handler()
if telemetry_handler:
# clear existing
telemetry_events.unregister_all_event_telemetries(telemetry_handler)
set_apptelemetry_handler(new_telemetry_handler)
# register handlers only if telemetry system is active
if apptelemetry_state:
apptelemetry_event_flags = get_apptelemetry_event_flags()
# re-register events with new telemetry_handler
telemetry_events.register_event_telemetry(
new_telemetry_handler,
apptelemetry_event_flags
)
user_config.save_changes()
``` | Back to top ## PyRevit Revit Wrapper [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/#pyrevit.revit) # revit Revit application wrapper. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Classes ### `BaseWrapper(obj=None)` Bases: `object` Base revit databse object wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
20
21
``` | ```md-code__content
def __init__(self, obj=None):
self._wrapped = obj
``` | #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `ElementWrapper(element)` Bases: `BaseWrapper` Revit element wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
62
63
64
65
66
``` | ```md-code__content
def __init__(self, element):
super(ElementWrapper, self).__init__(element)
if not isinstance(self._wrapped, DB.Element):
raise PyRevitException('Can not wrap object that are not '
'derived from Element.')
``` | #### Attributes ##### `assoc_doc``property` ##### `name``property` ##### `symbol_name``property` ##### `family_name``property` ##### `id``property` ##### `unique_id``property` ##### `workset_id``property` ##### `mark``property` ##### `location``property` ##### `x``property` ##### `y``property` ##### `z``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ##### `get_param(param_name)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
126
127
``` | ```md-code__content
def get_param(self, param_name):
return self._wrapped.LookupParameter(param_name)
``` | ##### `safe_get_param(param_name, default=None)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
129
130
131
132
133
``` | ```md-code__content
def safe_get_param(self, param_name, default=None):
try:
return self._wrapped.LookupParameter(param_name)
except Exception:
return default
``` | ### `ExternalRef(link, extref)` Bases: `ElementWrapper` External reference wraper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
138
139
140
``` | ```md-code__content
def __init__(self, link, extref):
super(ExternalRef, self).__init__(link)
self._extref = extref
``` | #### Attributes ##### `assoc_doc``property` ##### `symbol_name``property` ##### `family_name``property` ##### `id``property` ##### `unique_id``property` ##### `workset_id``property` ##### `mark``property` ##### `location``property` ##### `x``property` ##### `y``property` ##### `z``property` ##### `name``property` ##### `link``property` ##### `linktype``property` ##### `path``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ##### `get_param(param_name)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
126
127
``` | ```md-code__content
def get_param(self, param_name):
return self._wrapped.LookupParameter(param_name)
``` | ##### `safe_get_param(param_name, default=None)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
129
130
131
132
133
``` | ```md-code__content
def safe_get_param(self, param_name, default=None):
try:
return self._wrapped.LookupParameter(param_name)
except Exception:
return default
``` | ##### `reload()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
159
160
``` | ```md-code__content
def reload(self):
return self._wrapped.Reload()
``` | ### `ProjectParameter(param_def, param_binding=None, param_ext_def=False)` Bases: `BaseWrapper` Project parameter wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
``` | ```md-code__content
def __init__(self, param_def, param_binding=None, param_ext_def=False):
super(ProjectParameter, self).__init__()
self.param_def = param_def
self.param_binding = param_binding
self.param_binding_type = self._determine_binding_type()
self.shared = False
self.param_ext_def = None
self.param_guid = ''
if param_ext_def:
self.shared = True
self.param_ext_def = param_ext_def
self.param_guid = self.param_ext_def.GUID.ToString()
self.name = self.param_def.Name
# Revit <2017 does not have the Id parameter
self.param_id = getattr(self.param_def, 'Id', None)
if HOST_APP.is_exactly(2021):
# Revit >2021 does not have the UnitType property
self.unit_type = self.param_def.GetSpecTypeId()
self.param_type = self.param_def.ParameterType
self.param_group = self.param_def.ParameterGroup
elif HOST_APP.is_newer_than(2022, or_equal=True):
# GetSpecTypeId() Removed in Revit 2022
self.unit_type = self.param_def.GetDataType()
# Revit >2022 does not have the ParameterType property
self.param_type = self.param_def.GetDataType()
# ParameterGroup deprecated
self.param_group = self.param_def.GetGroupTypeId().TypeId
else:
self.unit_type = self.param_def.UnitType
self.param_type = self.param_def.ParameterType
self.param_group = self.param_def.ParameterGroup
``` | #### Attributes ##### `param_def = param_def``instance-attribute` ##### `param_binding = param_binding``instance-attribute` ##### `param_binding_type = self._determine_binding_type()``instance-attribute` ##### `shared = False``instance-attribute` ##### `param_ext_def = None``instance-attribute` ##### `param_guid = ''``instance-attribute` ##### `name = self.param_def.Name``instance-attribute` ##### `param_id = getattr(self.param_def, 'Id', None)``instance-attribute` ##### `unit_type = self.param_def.GetSpecTypeId()``instance-attribute` ##### `param_type = self.param_def.ParameterType``instance-attribute` ##### `param_group = self.param_def.ParameterGroup``instance-attribute` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `ProjectInfo(doc)` Bases: `BaseWrapper` Project information. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
221
222
223
``` | ```md-code__content
def __init__(self, doc):
super(ProjectInfo, self).__init__()
self._doc = doc
``` | #### Attributes ##### `name``property` ##### `number``property` ##### `address``property` ##### `author``property` ##### `building_name``property` ##### `client_name``property` ##### `issue_date``property` ##### `org_name``property` ##### `org_desc``property` ##### `status``property` ##### `location``property` ##### `path``property` ##### `filename``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `XYZPoint(obj=None)` Bases: `BaseWrapper` Wrapper for XYZ point. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
20
21
``` | ```md-code__content
def __init__(self, obj=None):
self._wrapped = obj
``` | #### Attributes ##### `x``property` ##### `y``property` ##### `z``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `Transaction(name=None, doc=None, clear_after_rollback=False, show_error_dialog=False, swallow_errors=False, log_errors=True, nested=False)` Adds a context manager around Revit Transaction object. Runs `Transaction.Start()` and `Transaction.Commit()` before and after the context. Automatically rolls back if exception is raised. \`\`\`python with Transaction('Move Wall'): wall.DoSomething() ```` with Transaction('Move Wall', doc, clear_after_rollback=False, show_error_dialog=False, swallow_errors=False, log_errors=True, nested=False)) as action: wall.DoSomething() assert action.status == ActionStatus.Started # True assert action.status == ActionStatus.Committed # True ``` ```` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
``` | ```md-code__content
def __init__(self, name=None,
doc=None,
clear_after_rollback=False,
show_error_dialog=False,
swallow_errors=False,
log_errors=True,
nested=False):
doc = doc or DOCS.doc
# create nested transaction if one is already open
if doc.IsModifiable or nested:
self._rvtxn = \
DB.SubTransaction(doc)
else:
self._rvtxn = \
DB.Transaction(doc, name if name else DEFAULT_TRANSACTION_NAME)
self._fhndlr_ops = self._rvtxn.GetFailureHandlingOptions()
self._fhndlr_ops = \
self._fhndlr_ops.SetClearAfterRollback(clear_after_rollback)
self._fhndlr_ops = \
self._fhndlr_ops.SetForcedModalHandling(show_error_dialog)
if swallow_errors:
self._fhndlr_ops = \
self._fhndlr_ops.SetFailuresPreprocessor(
failure.FailureSwallower()
)
self._rvtxn.SetFailureHandlingOptions(self._fhndlr_ops)
self._logerror = log_errors
``` | #### Attributes ##### `name``property``writable` ##### `status``property` #### Functions ##### `has_started()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
99
100
``` | ```md-code__content
def has_started(self):
return self._rvtxn.HasStarted()
``` | ##### `has_ended()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
102
103
``` | ```md-code__content
def has_ended(self):
return self._rvtxn.HasEnded()
``` | ### `DryTransaction(name=None, doc=None, clear_after_rollback=False, show_error_dialog=False, swallow_errors=False, log_errors=True, nested=False)` Bases: `Transaction` Wrapper to a transaction that doesn't commit anything (dry-run). Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
``` | ```md-code__content
def __init__(self, name=None,
doc=None,
clear_after_rollback=False,
show_error_dialog=False,
swallow_errors=False,
log_errors=True,
nested=False):
doc = doc or DOCS.doc
# create nested transaction if one is already open
if doc.IsModifiable or nested:
self._rvtxn = \
DB.SubTransaction(doc)
else:
self._rvtxn = \
DB.Transaction(doc, name if name else DEFAULT_TRANSACTION_NAME)
self._fhndlr_ops = self._rvtxn.GetFailureHandlingOptions()
self._fhndlr_ops = \
self._fhndlr_ops.SetClearAfterRollback(clear_after_rollback)
self._fhndlr_ops = \
self._fhndlr_ops.SetForcedModalHandling(show_error_dialog)
if swallow_errors:
self._fhndlr_ops = \
self._fhndlr_ops.SetFailuresPreprocessor(
failure.FailureSwallower()
)
self._rvtxn.SetFailureHandlingOptions(self._fhndlr_ops)
self._logerror = log_errors
``` | #### Attributes ##### `name``property``writable` ##### `status``property` #### Functions ##### `has_started()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
99
100
``` | ```md-code__content
def has_started(self):
return self._rvtxn.HasStarted()
``` | ##### `has_ended()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
102
103
``` | ```md-code__content
def has_ended(self):
return self._rvtxn.HasEnded()
``` | ### `TransactionGroup(name=None, doc=None, assimilate=True, log_errors=True)` Transactions group with context manager. Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
115
116
117
118
119
120
``` | ```md-code__content
def __init__(self, name=None, doc=None, assimilate=True, log_errors=True):
self._rvtxn_grp = \
DB.TransactionGroup(doc or DOCS.doc,
name if name else DEFAULT_TRANSACTION_NAME)
self.assimilate = assimilate
self._logerror = log_errors
``` | #### Attributes ##### `assimilate = assimilate``instance-attribute` ##### `name``property``writable` ##### `status``property` #### Functions ##### `has_started()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
158
159
``` | ```md-code__content
def has_started(self):
return self._rvtxn_grp.HasStarted()
``` | ##### `has_ended()` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
161
162
``` | ```md-code__content
def has_ended(self):
return self._rvtxn_grp.HasEnded()
``` | ### `RevitWrapper()` Bases: `ModuleType` Revit application wrapper. Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
55
56
``` | ```md-code__content
def __init__(self):
pass
``` | #### Attributes ##### `uidoc``property` Active UI Document. ##### `doc``property` Active document. ##### `docs``property` Active documents. ##### `active_view``property``writable` Active view. ##### `active_ui_view``property` Active UI view. ##### `servers``property` Available revit server names. #### Functions ##### `open_doc(doc_path)``staticmethod` Open document at given path. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc_path` | `str` | document file path | _required_ | Returns: | Type | Description | | --- | --- | | `Document` | opened document | Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
106
107
108
109
110
111
112
113
114
115
116
``` | ```md-code__content
@staticmethod
def open_doc(doc_path):
"""Open document at given path.
Args:
doc_path (str): document file path
Returns:
(DB.Document): opened document
"""
return HOST_APP.app.OpenDocumentFile(doc_path)
``` | ##### `close_doc(doc)``staticmethod` Close given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | document | _required_ | Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
118
119
120
121
122
123
124
125
``` | ```md-code__content
@staticmethod
def close_doc(doc):
"""Close given document.
Args:
doc (DB.Document): document
"""
return doc.Close()
``` | ##### `post_command(command_id)``staticmethod` Request Revit to run a command. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `command_id` | `str` | command identifier e.g. ID\_REVIT\_SAVE\_AS\_TEMPLATE | _required_ | Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
127
128
129
130
131
132
133
134
``` | ```md-code__content
@staticmethod
def post_command(command_id):
"""Request Revit to run a command.
Args:
command_id (str): command identifier e.g. ID_REVIT_SAVE_AS_TEMPLATE
"""
HOST_APP.post_command(command_id)
``` | ### `ErrorSwallower(log_errors=True)` Suppresses warnings during script execution. Examples: ```md-code__content with ErrorSwallower() as swallower: for fam in families: revit.doc.EditFamily(fam) if swallower.get_swallowed(): logger.warn("Warnings swallowed") ``` Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
150
151
152
``` | ```md-code__content
def __init__(self, log_errors=True):
self._fswallower = failure.FailureSwallower()
self._logerror = log_errors
``` | #### Functions ##### `on_failure_processing(_, event_args)` Failure processing event handler. Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
154
155
156
157
158
159
160
161
162
163
164
165
``` | ```md-code__content
def on_failure_processing(self, _, event_args):
"""Failure processing event handler."""
try:
failure_accesssor = event_args.GetFailuresAccessor()
mlogger.debug('request for failure processing...')
result = event_args.GetProcessingResult()
mlogger.debug('current failure processing result: %s', result)
result = self._fswallower.preprocess_failures(failure_accesssor)
mlogger.debug('setting failure processing results to: %s', result)
event_args.SetProcessingResult(result)
except Exception as fpex:
mlogger.error('Error occured while processing failures. | %s', fpex)
``` | ##### `get_swallowed_errors()` Return swallowed errors. Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
167
168
169
``` | ```md-code__content
def get_swallowed_errors(self):
"""Return swallowed errors."""
return self._fswallower.get_swallowed_failures()
``` | ##### `reset()` Reset swallowed errors. Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
171
172
173
``` | ```md-code__content
def reset(self):
"""Reset swallowed errors."""
self._fswallower.reset()
``` | ## Functions ### `carryout(name, doc=None)` Transaction Decorator. Decorate any function with `@doc.carryout('Txn name')` and the funciton will run within an Transaction context. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `name` | `str` | Name of the Transaction | _required_ | | `doc` | `Document` | Revit document | `None` | ```md-code__content @doc.carryout('Do Something') def set_some_parameter(wall, value): wall.parameters['Comments'].value = value set_some_parameter(wall, value) ``` Source code in `pyrevitlib/pyrevit/revit/db/transaction.py` | | | | --- | --- | | ```
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
``` | ````md-code__content
def carryout(name, doc=None):
"""Transaction Decorator.
Decorate any function with ``@doc.carryout('Txn name')``
and the funciton will run within an Transaction context.
Args:
name (str): Name of the Transaction
doc (Document): Revit document
```python
@doc.carryout('Do Something')
def set_some_parameter(wall, value):
wall.parameters['Comments'].value = value
set_some_parameter(wall, value)
```
"""
from functools import wraps
def wrap(f):
@wraps(f)
def wrapped_f(*args, **kwargs):
with Transaction(name, doc=doc):
return_value = f(*args, **kwargs)
return return_value
return wrapped_f
return wrap
```` | ### `serialize(api_object)` Source code in `pyrevitlib/pyrevit/revit/db/pickling.py` | | | | --- | --- | | ```
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
``` | ```md-code__content
def serialize(api_object):
mlogger.debug('Attemping to serialize: %s', api_object)
# wrap none in a none serializer for none values
if api_object is None:
return NoneSerializer()
# make sure given type is a Revit API type
if not api.is_api_object(api_object):
raise PyRevitException("Only Revit API types are supported.")
# get available serializers
serializers = coreutils.get_all_subclasses(
[Serializable, EnumSerializable]
)
# pick the compatible serializer
try:
compatible_serializer = \
next(
x for x in serializers
if x.api_types and isinstance(api_object, x.api_types)
)
mlogger.debug('Serializer found for: %s', api_object)
return compatible_serializer(api_object)
except StopIteration:
mlogger.debug('Serializer not found for: %s', api_object)
# if no deserializer found,
# see if given data is iterable
# NOTE: commented this out since .serialize should only get api objects
# if isinstance(api_object, Iterable):
# mlogger.debug('Iterating over: %s', api_object)
# return _serialize_items(api_object)
# otherwise throw an exception
raise PyRevitException(
"No serializers have been implemented for \"%s\"" % repr(api_object)
)
``` | ### `deserialize(python_object)` Source code in `pyrevitlib/pyrevit/revit/db/pickling.py` | | | | --- | --- | | ```
249
250
251
252
253
254
255
256
257
``` | ```md-code__content
def deserialize(python_object):
if isinstance(python_object, Iterable):
result_list = []
for python_item in python_object:
result_list.append(deserialize(python_item))
return result_list
if isinstance(python_object, Serializable):
return python_object.deserialize()
``` | ### `get_journals_folder()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
12
13
``` | ```md-code__content
def get_journals_folder():
return op.dirname(HOST_APP.app.RecordingJournalFilename)
``` | ### `get_current_journal_file()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
16
17
``` | ```md-code__content
def get_current_journal_file():
return HOST_APP.app.RecordingJournalFilename
``` | ### `get_current_session_id()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
20
21
22
23
24
25
26
27
``` | ```md-code__content
def get_current_session_id():
re_finder = re.compile(r'.*>Session\s+(\$.{8}).*')
journal_file = get_current_journal_file()
with open(journal_file, "r") as jfile:
for jline in reversed(jfile.readlines()):
match = re_finder.match(jline)
if match:
return match.groups()[0]
``` | ### `pick_element(message='')` Asks the user to pick an element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | An optional message to display. | `''` | Returns: | Type | Description | | --- | --- | | `Element` | element selected by the user. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
198
199
200
201
202
203
204
205
206
207
208
``` | ```md-code__content
def pick_element(message=''):
"""Asks the user to pick an element.
Args:
message (str): An optional message to display.
Returns:
(Element): element selected by the user.
"""
return _pick_obj(UI.Selection.ObjectType.Element,
message)
``` | ### `pick_element_by_category(cat_name_or_builtin, message='')` Returns the element of the specified category picked by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | name or built-in category of the element
to pick. | _required_ | | `message` | `str` | message to display on selection.
Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Element` | picked element. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If no category matches the specified name or builtin. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
``` | ```md-code__content
def pick_element_by_category(cat_name_or_builtin, message=''):
"""Returns the element of the specified category picked by the user.
Args:
cat_name_or_builtin (str): name or built-in category of the element
to pick.
message (str, optional): message to display on selection.
Defaults to ''.
Returns:
(Element): picked element.
Raises:
PyRevitException: If no category matches the specified name or builtin.
"""
category = query.get_category(cat_name_or_builtin)
if category:
pick_filter = PickByCategorySelectionFilter(category.Id)
return _pick_obj(UI.Selection.ObjectType.Element,
message,
selection_filter=pick_filter)
else:
raise PyRevitException("Can not determine category id from: {}"
.format(cat_name_or_builtin))
``` | ### `pick_elementpoint(message='', world=False)` Returns the element point selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | | `world` | `bool` | whether to use world coordinates. Defaults to False. | `False` | Returns: | Type | Description | | --- | --- | | `PointOnElement` | The selected point. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
237
238
239
240
241
242
243
244
245
246
247
248
249
``` | ```md-code__content
def pick_elementpoint(message='', world=False):
"""Returns the element point selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
world (bool, optional): whether to use world coordinates. Defaults to False.
Returns:
(PointOnElement): The selected point.
"""
return _pick_obj(UI.Selection.ObjectType.PointOnElement,
message,
world=world)
``` | ### `pick_edge(message='')` Returns the edge selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Edge` | The selected edge. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
252
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def pick_edge(message=''):
"""Returns the edge selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(Edge): The selected edge.
"""
return _pick_obj(UI.Selection.ObjectType.Edge,
message)
``` | ### `pick_face(message='')` Returns the face selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Face` | The selected face. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
265
266
267
268
269
270
271
272
273
274
275
``` | ```md-code__content
def pick_face(message=''):
"""Returns the face selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(Face): The selected face.
"""
return _pick_obj(UI.Selection.ObjectType.Face,
message)
``` | ### `pick_linked(message='')` Returns the linked element selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `LinkedElement` | The selected linked element. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
278
279
280
281
282
283
284
285
286
287
288
``` | ```md-code__content
def pick_linked(message=''):
"""Returns the linked element selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(LinkedElement): The selected linked element.
"""
return _pick_obj(UI.Selection.ObjectType.LinkedElement,
message)
``` | ### `pick_elements(message='')` Asks the user to pick multiple elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | An optional message to display. | `''` | Returns: | Type | Description | | --- | --- | | `list[Element]` | elements selected by the user. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
``` | ```md-code__content
def pick_elements(message=''):
"""Asks the user to pick multiple elements.
Args:
message (str): An optional message to display.
Returns:
(list[Element]): elements selected by the user.
"""
return _pick_obj(UI.Selection.ObjectType.Element,
message,
multiple=True)
``` | ### `pick_elements_by_category(cat_name_or_builtin, message='')` Returns the elements of the specified category picked by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | name or built-in category of the elements
to pick. | _required_ | | `message` | `str` | message to display on selection.
Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `list[Element]` | picked elements. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If no category matches the specified name or builtin. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
``` | ```md-code__content
def pick_elements_by_category(cat_name_or_builtin, message=''):
"""Returns the elements of the specified category picked by the user.
Args:
cat_name_or_builtin (str): name or built-in category of the elements
to pick.
message (str, optional): message to display on selection.
Defaults to ''.
Returns:
(list[Element]): picked elements.
Raises:
PyRevitException: If no category matches the specified name or builtin.
"""
category = query.get_category(cat_name_or_builtin)
if category:
pick_filter = PickByCategorySelectionFilter(category.Id)
return _pick_obj(UI.Selection.ObjectType.Element,
message,
multiple=True,
selection_filter=pick_filter)
else:
raise PyRevitException("Can not determine category id from: {}"
.format(cat_name_or_builtin))
``` | ### `get_picked_elements(message='')` Allows the user to pick multple elements, one at a time. It keeps asking the user to pick an element until no elements are selected. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display. Defaults to ''. | `''` | Yields: | Type | Description | | --- | --- | | `Element` | selected element | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
``` | ```md-code__content
def get_picked_elements(message=''):
"""Allows the user to pick multple elements, one at a time.
It keeps asking the user to pick an element until no elements are selected.
Args:
message (str, optional): The message to display. Defaults to ''.
Yields:
(DB.Element): selected element
"""
picked_element = True
while picked_element:
picked_element = pick_element(message=message)
if not picked_element:
break
yield picked_element
``` | ### `get_picked_elements_by_category(cat_name_or_builtin, message='')` Pick elements by category. Keeps asking the user to pick an element until no elements are selected. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | category name or built-in category. | _required_ | | `message` | `str` | message to display while picking elements. | `''` | Yields: | Type | Description | | --- | --- | | `Element` | The picked elements from the specified category. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
``` | ```md-code__content
def get_picked_elements_by_category(cat_name_or_builtin, message=''):
"""Pick elements by category.
Keeps asking the user to pick an element until no elements are selected.
Args:
cat_name_or_builtin (str): category name or built-in category.
message (str, optional): message to display while picking elements.
Yields:
(DB.Element): The picked elements from the specified category.
"""
picked_element = True
while picked_element:
picked_element = pick_element_by_category(cat_name_or_builtin,
message=message)
if not picked_element:
break
yield picked_element
``` | ### `pick_elementpoints(message='', world=False)` Selects element points. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting element points. | `''` | | `world` | `bool` | Select points in world coordinates. Defaults to False. | `False` | Returns: | Type | Description | | --- | --- | | `list[PointOnElement]` | selected element points. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
372
373
374
375
376
377
378
379
380
381
382
383
384
``` | ```md-code__content
def pick_elementpoints(message='', world=False):
"""Selects element points.
Args:
message (str): The message to display when selecting element points.
world (bool, optional): Select points in world coordinates. Defaults to False.
Returns:
(list[PointOnElement]): selected element points.
"""
return _pick_obj(UI.Selection.ObjectType.PointOnElement,
message,
multiple=True, world=world)
``` | ### `pick_edges(message='')` Selects edges. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting edges. | `''` | Returns: | Type | Description | | --- | --- | | `list[Edge]` | selected edges. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
387
388
389
390
391
392
393
394
395
396
397
398
``` | ```md-code__content
def pick_edges(message=''):
"""Selects edges.
Args:
message (str): The message to display when selecting edges.
Returns:
(list[Edge]): selected edges.
"""
return _pick_obj(UI.Selection.ObjectType.Edge,
message,
multiple=True)
``` | ### `pick_faces(message='')` Selects faces. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting the faces. | `''` | Returns: | Type | Description | | --- | --- | | `list[Face]` | selected faces. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
401
402
403
404
405
406
407
408
409
410
411
412
``` | ```md-code__content
def pick_faces(message=''):
"""Selects faces.
Args:
message (str): The message to display when selecting the faces.
Returns:
(list[Face]): selected faces.
"""
return _pick_obj(UI.Selection.ObjectType.Face,
message,
multiple=True)
``` | ### `pick_linkeds(message='')` Selects linked elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting linked elements. | `''` | Returns: | Type | Description | | --- | --- | | `list[LinkedElement]` | selected linked elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
def pick_linkeds(message=''):
"""Selects linked elements.
Args:
message (str): The message to display when selecting linked elements.
Returns:
(list[LinkedElement]): selected linked elements.
"""
return _pick_obj(UI.Selection.ObjectType.LinkedElement,
message,
multiple=True)
``` | ### `pick_point(message='')` Pick a point from the user interface. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | A message to display when prompting for the point. | `''` | Returns: | Type | Description | | --- | --- | | `tuple or None` | A tuple representing the picked point as (x, y, z)
coordinates, or None if no point was picked or an error occurred. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
429
430
431
432
433
434
435
436
437
438
439
440
441
442
``` | ```md-code__content
def pick_point(message=''):
"""Pick a point from the user interface.
Args:
message (str): A message to display when prompting for the point.
Returns:
(tuple or None): A tuple representing the picked point as (x, y, z)
coordinates, or None if no point was picked or an error occurred.
"""
try:
return HOST_APP.uidoc.Selection.PickPoint(message)
except Exception:
return None
``` | ### `pick_rectangle(message='', pick_filter=None)` Picks elements from the user interface by specifying a rectangular area. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | A custom message to display when prompting
the user to pick elements. Default is an empty string. | `''` | | `pick_filter` | `object` | An object specifying the filter to apply
when picking elements. Default is None. | `None` | Returns: | Type | Description | | --- | --- | | `list[ElementId]` | The selected elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
``` | ```md-code__content
def pick_rectangle(message='', pick_filter=None):
"""Picks elements from the user interface by specifying a rectangular area.
Args:
message (str, optional): A custom message to display when prompting
the user to pick elements. Default is an empty string.
pick_filter (object, optional): An object specifying the filter to apply
when picking elements. Default is None.
Returns:
(list[DB.ElementId]): The selected elements.
"""
if pick_filter:
return HOST_APP.uidoc.Selection.PickElementsByRectangle(pick_filter,
message)
else:
return HOST_APP.uidoc.Selection.PickElementsByRectangle(message)
``` | ### `get_selection_category_set()` Returns a CategorySet with the categories of the selected elements. Returns: | Type | Description | | --- | --- | | `CategorySet` | categories of the selected elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
464
465
466
467
468
469
470
471
472
473
474
``` | ```md-code__content
def get_selection_category_set():
"""Returns a CategorySet with the categories of the selected elements.
Returns:
(CategorySet): categories of the selected elements.
"""
selection = ElementSelection()
cset = DB.CategorySet()
for element in selection:
cset.Insert(element.Category)
return cset
``` | ### `get_selection()` Returns the current selected items. Returns: | Type | Description | | --- | --- | | `ElementSelection` | the current selected items | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
477
478
479
480
481
482
483
``` | ```md-code__content
def get_selection():
"""Returns the current selected items.
Returns:
(ElementSelection): the current selected items
"""
return ElementSelection()
``` | ### `get_imported_symbol(symbol_name)` Geth an imported symbol by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `symbol_name` | `str` | symbol name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | imported symbol, if found, None otherwise. | Source code in `pyrevitlib/pyrevit/revit/__init__.py` | | | | --- | --- | | ```
41
42
43
44
45
46
47
48
49
50
``` | ```md-code__content
def get_imported_symbol(symbol_name):
"""Geth an imported symbol by its name.
Args:
symbol_name (str): symbol name
Returns:
(Any): imported symbol, if found, None otherwise.
"""
return globals().get(symbol_name, None)
``` | Back to top ## PyRevit Runtime Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/#pyrevit.runtime) # runtime Module that compiles the base DLL on load. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `INTERFACE_TYPES_DIR = RUNTIME_DIR``module-attribute` ### `DOTNET_DIR = op.join(os.getenv('windir'), 'Microsoft.NET', 'Framework')``module-attribute` ### `DOTNET64_DIR = op.join(os.getenv('windir'), 'Microsoft.NET', 'Framework64')``module-attribute` ### `DOTNET_SDK_DIR = op.join(os.getenv('programfiles(x86)'), 'Reference Assemblies', 'Microsoft', 'Framework', '.NETFramework')``module-attribute` ### `DOTNET_FRAMEWORK_DIRS = sorted([x for x in os.listdir(DOTNET_DIR) if x.startswith('v4.') and 'X' not in x], reverse=True)``module-attribute` ### `DOTNET64_FRAMEWORK_DIRS = sorted([x for x in os.listdir(DOTNET64_DIR) if x.startswith('v4.') and 'X' not in x], reverse=True)``module-attribute` ### `DOTNET_TARGETPACK_DIRS = sorted([x for x in os.listdir(DOTNET_SDK_DIR) if x.startswith('v4.') and 'X' not in x], reverse=True)``module-attribute` ### `RUNTIME_NAMESPACE = 'PyRevitLabs.PyRevit.Runtime'``module-attribute` ### `CMD_EXECUTOR_TYPE_NAME = '{}.{}'.format(RUNTIME_NAMESPACE, 'ScriptCommand')``module-attribute` ### `CMD_AVAIL_TYPE_NAME_EXTENDED = coreutils.make_canonical_name(RUNTIME_NAMESPACE, 'ScriptCommandExtendedAvail')``module-attribute` ### `CMD_AVAIL_TYPE_NAME_SELECTION = coreutils.make_canonical_name(RUNTIME_NAMESPACE, 'ScriptCommandSelectionAvail')``module-attribute` ### `CMD_AVAIL_TYPE_NAME_ZERODOC = coreutils.make_canonical_name(RUNTIME_NAMESPACE, 'ScriptCommandZeroDocAvail')``module-attribute` ### `CMD_AVAIL_NAME_POSTFIX = '-avail'``module-attribute` ### `SOURCE_FILE_EXT = '.cs'``module-attribute` ### `SOURCE_FILE_FILTER = '(\\.cs)'``module-attribute` ### `CPYTHON_ENGINE = user_config.get_active_cpython_engine()``module-attribute` ### `BASE_TYPES_DIR_HASH = coreutils.get_str_hash(coreutils.calculate_dir_hash(INTERFACE_TYPES_DIR, '', SOURCE_FILE_FILTER) + EXEC_PARAMS.engine_ver + str(CPYTHON_ENGINE.Version) if CPYTHON_ENGINE else '0')[:HASH_CUTOFF_LENGTH]``module-attribute` ### `RUNTIME_ASSM_FILE_ID = '{}_{}'.format(BASE_TYPES_DIR_HASH, RUNTIME_NAMESPACE)``module-attribute` ### `RUNTIME_ASSM_FILE = op.join(BIN_DIR, 'pyRevitLabs.PyRevit.Runtime.{}.dll'.format(HOST_APP.version))``module-attribute` ### `RUNTIME_ASSM_NAME = op.splitext(op.basename(RUNTIME_ASSM_FILE))[0]``module-attribute` ### `RUNTIME_ASSM = None``module-attribute` ### `assm_list = assmutils.find_loaded_asm(RUNTIME_ASSM_NAME)``module-attribute` ### `CMD_EXECUTOR_TYPE = assmutils.find_type_by_name(RUNTIME_ASSM, CMD_EXECUTOR_TYPE_NAME)``module-attribute` ### `CMD_AVAIL_TYPE_EXTENDED = assmutils.find_type_by_name(RUNTIME_ASSM, CMD_AVAIL_TYPE_NAME_EXTENDED)``module-attribute` ### `CMD_AVAIL_TYPE_SELECTION = assmutils.find_type_by_name(RUNTIME_ASSM, CMD_AVAIL_TYPE_NAME_SELECTION)``module-attribute` ### `CMD_AVAIL_TYPE_ZERODOC = assmutils.find_type_by_name(RUNTIME_ASSM, CMD_AVAIL_TYPE_NAME_ZERODOC)``module-attribute` ## Classes ## Functions ### `get_references()` Get list of all referenced assemblies. Returns: | Type | Description | | --- | --- | | `list` | referenced assemblies | Source code in `pyrevitlib/pyrevit/runtime/__init__.py` | | | | --- | --- | | ```
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
``` | ```md-code__content
def get_references():
"""Get list of all referenced assemblies.
Returns:
(list): referenced assemblies
"""
ref_list = [
# system stuff
'System', 'System.Core', 'System.Runtime', 'System.Linq', 'System.Collections',
'System.Collections.Immutable', 'System.Console',
'System.Xaml', 'System.Web', 'System.Xml', 'System.Numerics',
'System.Drawing', 'System.Windows.Forms',
'System.ComponentModel.Primitives', 'System.ComponentModel.TypeConverter',
'PresentationCore', 'PresentationFramework',
'WindowsBase', 'WindowsFormsIntegration',
# legacy csharp/vb.net compiler
'Microsoft.CSharp',
# iron python engine
'{prefix}Microsoft.Dynamic'.format(prefix=eng.EnginePrefix),
'{prefix}Microsoft.Scripting'.format(prefix=eng.EnginePrefix),
'{prefix}IronPython'.format(prefix=eng.EnginePrefix),
'{prefix}IronPython.Modules'.format(prefix=eng.EnginePrefix),
# revit api
'RevitAPI', 'RevitAPIUI', 'AdWindows', 'UIFramework',
# pyrevit loader assembly
'pyRevitLoader',
# pyrevit labs
'pyRevitLabs.Common', 'pyRevitLabs.CommonWPF',
'pyRevitLabs.MahAppsMetro',
'pyRevitLabs.NLog',
'pyRevitLabs.Json',
'pyRevitLabs.Emojis',
'pyRevitLabs.TargetApps.Revit',
'pyRevitLabs.PyRevit',
'pyRevitLabs.PyRevit.Runtime.Shared',
]
# netcore depends
if NETCORE:
ref_list.extend(['System.Drawing.Common',
'System.Diagnostics.Process',
'System.Diagnostics.FileVersionInfo',
'System.Text.RegularExpressions'])
# another revit api
if HOST_APP.is_newer_than(2018):
ref_list.extend(['Xceed.Wpf.AvalonDock'])
refs = (_get_reference_file(ref_name) for ref_name in ref_list)
return [r for r in refs if r]
``` | ### `create_ipyengine_configs(clean=False, full_frame=False, persistent=False)` Return the configuration for ipython engine. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `clean` | `bool` | Engine should be clean. Defaults to False. | `False` | | `full_frame` | `bool` | Engine shoul be full frame. Defaults to False. | `False` | | `persistent` | `bool` | Engine should persist. Defaults to False. | `False` | Returns: | Type | Description | | --- | --- | | `str` | Configuration | Source code in `pyrevitlib/pyrevit/runtime/__init__.py` | | | | --- | --- | | ```
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
``` | ```md-code__content
def create_ipyengine_configs(clean=False, full_frame=False, persistent=False):
"""Return the configuration for ipython engine.
Args:
clean (bool, optional): Engine should be clean. Defaults to False.
full_frame (bool, optional): Engine shoul be full frame. Defaults to False.
persistent (bool, optional): Engine should persist. Defaults to False.
Returns:
(str): Configuration
"""
return json.dumps({
exts.MDATA_ENGINE_CLEAN: clean,
exts.MDATA_ENGINE_FULLFRAME: full_frame,
exts.MDATA_ENGINE_PERSISTENT: persistent,
})
``` | ### `create_ext_command_attrs()` Create dotnet attributes for Revit external commands. This method is used in creating custom dotnet types for pyRevit commands and compiling them into a DLL assembly. Current implementation sets `RegenerationOption.Manual` and `TransactionMode.Manual` Returns: | Type | Description | | --- | --- | | `list[CustomAttributeBuilder]` | object for `RegenerationOption`
and `TransactionMode` attributes. | Source code in `pyrevitlib/pyrevit/runtime/__init__.py` | | | | --- | --- | | ```
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
``` | ```md-code__content
def create_ext_command_attrs():
"""Create dotnet attributes for Revit external commands.
This method is used in creating custom dotnet types for pyRevit commands
and compiling them into a DLL assembly. Current implementation sets
``RegenerationOption.Manual`` and ``TransactionMode.Manual``
Returns:
(list[CustomAttributeBuilder]): object for `RegenerationOption`
and `TransactionMode` attributes.
"""
regen_const_info = \
framework.clr.GetClrType(api.Attributes.RegenerationAttribute) \
.GetConstructor(
framework.Array[framework.Type](
(api.Attributes.RegenerationOption,)
))
regen_attr_builder = \
framework.CustomAttributeBuilder(
regen_const_info,
framework.Array[object](
(api.Attributes.RegenerationOption.Manual,)
))
# add TransactionAttribute to framework.Type
trans_constructor_info = \
framework.clr.GetClrType(api.Attributes.TransactionAttribute) \
.GetConstructor(
framework.Array[framework.Type](
(api.Attributes.TransactionMode,)
)
)
trans_attrib_builder = \
framework.CustomAttributeBuilder(
trans_constructor_info,
framework.Array[object](
(api.Attributes.TransactionMode.Manual,)
)
)
return [regen_attr_builder, trans_attrib_builder]
``` | ### `create_type(modulebuilder, type_class, class_name, custom_attr_list, *args)` Create a dotnet type for a pyRevit command. See `baseclasses.cs` code for the template pyRevit command dotnet type and its constructor default arguments that must be provided here. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `modulebuilder` | | obj: `ModuleBuilder`): dotnet module builder | _required_ | | `type_class` | `type` | source dotnet type for the command | _required_ | | `class_name` | `str` | name for the new type | _required_ | | `custom_attr_list` | | obj: `list`): list of dotnet attributes for the type | _required_ | | `*args` | `Any` | list of arguments to be used with type constructor | `()` | Returns: | Type | Description | | --- | --- | | `type` | returns created dotnet type | Examples: ```md-code__content asm_builder = AppDomain.CurrentDomain.DefineDynamicAssembly( win_asm_name, AssemblyBuilderAccess.RunAndSave, filepath ) module_builder = asm_builder.DefineDynamicModule( ext_asm_file_name, ext_asm_full_file_name ) create_type( module_builder, runtime.ScriptCommand, "PyRevitSomeCommandUniqueName", runtime.create_ext_command_attrs(), [scriptpath, atlscriptpath, searchpath, helpurl, name,\ bundle, extension, uniquename, False, False]) ``` Source code in `pyrevitlib/pyrevit/runtime/__init__.py` | | | | --- | --- | | ```
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
``` | ````md-code__content
def create_type(modulebuilder, type_class, class_name, custom_attr_list, *args):
"""Create a dotnet type for a pyRevit command.
See ``baseclasses.cs`` code for the template pyRevit command dotnet type
and its constructor default arguments that must be provided here.
Args:
modulebuilder (:obj:`ModuleBuilder`): dotnet module builder
type_class (type): source dotnet type for the command
class_name (str): name for the new type
custom_attr_list (:obj:`list`): list of dotnet attributes for the type
*args (Any): list of arguments to be used with type constructor
Returns:
(type): returns created dotnet type
Examples:
```python
asm_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
win_asm_name, AssemblyBuilderAccess.RunAndSave, filepath
)
module_builder = asm_builder.DefineDynamicModule(
ext_asm_file_name, ext_asm_full_file_name
)
create_type(
module_builder,
runtime.ScriptCommand,
"PyRevitSomeCommandUniqueName",
runtime.create_ext_command_attrs(),
[scriptpath, atlscriptpath, searchpath, helpurl, name,
bundle, extension, uniquename, False, False])
```

"""
# create type builder
type_builder = \
modulebuilder.DefineType(
class_name,
framework.TypeAttributes.Class | framework.TypeAttributes.Public,
type_class
)
for custom_attr in custom_attr_list:
type_builder.SetCustomAttribute(custom_attr)
# prepare a list of input param types to find the matching constructor
type_list = []
param_list = []
for param in args:
if isinstance(param, str) \
or isinstance(param, int):
type_list.append(type(param))
param_list.append(param)
# call base constructor
constructor = \
type_class.GetConstructor(framework.Array[framework.Type](type_list))
# create class constructor builder
const_builder = \
type_builder.DefineConstructor(framework.MethodAttributes.Public,
framework.CallingConventions.Standard,
framework.Array[framework.Type](()))
# add constructor parameters to stack
gen = const_builder.GetILGenerator()
gen.Emit(framework.OpCodes.Ldarg_0) # Load "this" onto eval stack
# add constructor input params to the stack
for param_type, param in zip(type_list, param_list):
if param_type == str:
gen.Emit(framework.OpCodes.Ldstr, param)
elif param_type == int:
gen.Emit(framework.OpCodes.Ldc_I4, param)
# call base constructor (consumes "this" and the created stack)
gen.Emit(framework.OpCodes.Call, constructor)
# Fill some space - this is how it is generated for equivalent C# code
gen.Emit(framework.OpCodes.Nop)
gen.Emit(framework.OpCodes.Nop)
gen.Emit(framework.OpCodes.Nop)
gen.Emit(framework.OpCodes.Ret)
return type_builder.CreateType()
```` | Back to top ## pyRevit Script Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/script/#pyrevit.script) # script Provide basic utilities for pyRevit scripts. Examples: ```md-code__content from pyrevit import script script.clipboard_copy('some text') data = script.journal_read('data-key') script.exit() ``` ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `DATAFEXT = 'pym'``module-attribute` ### `ICON_SMALL = 16``module-attribute` ### `ICON_MEDIUM = 24``module-attribute` ### `ICON_LARGE = 32``module-attribute` ## Classes ## Functions ### `get_info()` Return info on current pyRevit command. Returns: | Type | Description | | --- | --- | | `GenericUICommand` | Command info object | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
58
``` | ```md-code__content
def get_info():
"""Return info on current pyRevit command.
Returns:
(pyrevit.extensions.genericcomps.GenericUICommand):
Command info object
"""
return get_command_from_path(EXEC_PARAMS.command_path)
``` | ### `get_command_from_path(comp_path)` Returns a pyRevit command object from the given bundle directory. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `comp_path` | `str` | Full directory address of the command bundle | _required_ | Returns: | Type | Description | | --- | --- | | `GenericUICommand` | A subclass of pyRevit command object. | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
61
62
63
64
65
66
67
68
69
70
71
72
73
74
``` | ```md-code__content
def get_command_from_path(comp_path):
"""Returns a pyRevit command object from the given bundle directory.
Args:
comp_path (str): Full directory address of the command bundle
Returns:
(genericcomps.GenericUICommand): A subclass of pyRevit command object.
"""
cmds = parse_comp_dir(comp_path, GenericUICommand)
if cmds:
return cmds[0]
return None
``` | ### `get_script_path()` Return script path of the current pyRevit command. Returns: | Type | Description | | --- | --- | | `str` | script path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
77
78
79
80
81
82
83
``` | ```md-code__content
def get_script_path():
"""Return script path of the current pyRevit command.
Returns:
(str): script path
"""
return EXEC_PARAMS.command_path
``` | ### `get_alt_script_path()` Return config script path of the current pyRevit command. Returns: | Type | Description | | --- | --- | | `str` | config script path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
86
87
88
89
90
91
92
``` | ```md-code__content
def get_alt_script_path():
"""Return config script path of the current pyRevit command.
Returns:
(str): config script path
"""
return EXEC_PARAMS.command_config_path
``` | ### `get_bundle_name()` Return bundle name of the current pyRevit command. Returns: | Type | Description | | --- | --- | | `str` | bundle name (e.g. MyButton.pushbutton) | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
95
96
97
98
99
100
101
``` | ```md-code__content
def get_bundle_name():
"""Return bundle name of the current pyRevit command.
Returns:
(str): bundle name (e.g. MyButton.pushbutton)
"""
return EXEC_PARAMS.command_bundle
``` | ### `get_extension_name()` Return extension name of the current pyRevit command. Returns: | Type | Description | | --- | --- | | `str` | extension name (e.g. MyExtension.extension) | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
104
105
106
107
108
109
110
``` | ```md-code__content
def get_extension_name():
"""Return extension name of the current pyRevit command.
Returns:
(str): extension name (e.g. MyExtension.extension)
"""
return EXEC_PARAMS.command_extension
``` | ### `get_unique_id()` Return unique id of the current pyRevit command. Returns: | Type | Description | | --- | --- | | `str` | command unique id | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
113
114
115
116
117
118
119
``` | ```md-code__content
def get_unique_id():
"""Return unique id of the current pyRevit command.
Returns:
(str): command unique id
"""
return EXEC_PARAMS.command_uniqueid
``` | ### `get_results()` Return command results dictionary for logging. Returns: | Type | Description | | --- | --- | | `CommandCustomResults` | Command results dict | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
122
123
124
125
126
127
128
129
130
``` | ```md-code__content
def get_results():
"""Return command results dictionary for logging.
Returns:
(pyrevit.telemetry.record.CommandCustomResults):
Command results dict
"""
from pyrevit.telemetry.record import CommandCustomResults
return CommandCustomResults()
``` | ### `get_pyrevit_version()` Return pyRevit version. Returns: | Type | Description | | --- | --- | | `_PyRevitVersion` | pyRevit version provider | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
133
134
135
136
137
138
139
``` | ```md-code__content
def get_pyrevit_version():
"""Return pyRevit version.
Returns:
(pyrevit.versionmgr._PyRevitVersion): pyRevit version provider
"""
return versionmgr.get_pyrevit_version()
``` | ### `get_logger()` Create and return logger named for current script. Returns: | Type | Description | | --- | --- | | `LoggerWrapper` | Logger object | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
142
143
144
145
146
147
148
``` | ```md-code__content
def get_logger():
"""Create and return logger named for current script.
Returns:
(pyrevit.coreutils.logger.LoggerWrapper): Logger object
"""
return logger.get_logger(EXEC_PARAMS.command_name)
``` | ### `get_output()` Return object wrapping output window for current script. Returns: | Type | Description | | --- | --- | | `PyRevitOutputWindow` | Output wrapper object | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
151
152
153
154
155
156
157
``` | ```md-code__content
def get_output():
"""Return object wrapping output window for current script.
Returns:
(pyrevit.output.PyRevitOutputWindow): Output wrapper object
"""
return output.get_output()
``` | ### `get_config(section=None)` Create and return config section parser object for current script. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `section` | `str` | config section name. If not provided,
it will default to the command name plus the 'config' suffix. | `None` | Returns: | Type | Description | | --- | --- | | `PyRevitConfigSectionParser` | Config section parser object | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
``` | ```md-code__content
def get_config(section=None):
"""Create and return config section parser object for current script.
Args:
section (str, optional): config section name. If not provided,
it will default to the command name plus the 'config' suffix.
Returns:
(pyrevit.coreutils.configparser.PyRevitConfigSectionParser):
Config section parser object
"""
from pyrevit.userconfig import user_config
if not section:
script_cfg_postfix = 'config'
section = EXEC_PARAMS.command_name + script_cfg_postfix
try:
return user_config.get_section(section)
except AttributeError:
return user_config.add_section(section)
``` | ### `save_config()` Save pyRevit config. Scripts should call this to save any changes they have done to their config section object received from script.get\_config() method. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
182
183
184
185
186
187
188
189
``` | ```md-code__content
def save_config():
"""Save pyRevit config.
Scripts should call this to save any changes they have done to their
config section object received from script.get_config() method.
"""
from pyrevit.userconfig import user_config
user_config.save_changes()
``` | ### `reset_config(section=None)` Reset pyRevit config. Script should call this to reset any save configuration by removing section related to current script. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `section` | `str` | config section name | `None` | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
``` | ```md-code__content
def reset_config(section=None):
"""Reset pyRevit config.
Script should call this to reset any save configuration by removing
section related to current script.
Args:
section (str, optional): config section name
"""
from pyrevit.userconfig import user_config
if not section:
script_cfg_postfix = 'config'
section = EXEC_PARAMS.command_name + script_cfg_postfix
elif section in [PyRevit.PyRevitConsts.ConfigsCoreSection]:
raise PyRevitException('Can not remove internal config section: {}'
.format(section))
try:
user_config.remove_section(section)
user_config.save_changes()
except Exception:
mlogger.debug('Failed resetting config for %s (%s)',
EXEC_PARAMS.command_name, section)
``` | ### `get_universal_data_file(file_id, file_ext, add_cmd_name=False)` Return filename to be used by a user script to store data. File name is generated in this format: `pyRevit_{file_id}.{file_ext}` Examples: ```md-code__content script.get_universal_data_file('mydata', 'data') ``` '/pyRevit\_mydata.data' ```md-code__content script.get_universal_data_file('mydata', 'data', add_cmd_name=True) ``` '/pyRevit\_Command Name\_mydata.data' Universal data files are not cleaned up at pyRevit startup. Script should manage cleaning up these files. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | unique id for the filename | _required_ | | `file_ext` | `str` | file extension | _required_ | | `add_cmd_name` | `bool` | add command name to file name | `False` | Returns: | Type | Description | | --- | --- | | `str` | full file path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
``` | ````md-code__content
def get_universal_data_file(file_id, file_ext, add_cmd_name=False):
"""Return filename to be used by a user script to store data.
File name is generated in this format:
``pyRevit_{file_id}.{file_ext}``
Examples:
```python
script.get_universal_data_file('mydata', 'data')
```
'/pyRevit_mydata.data'
```python
script.get_universal_data_file('mydata', 'data', add_cmd_name=True)
```
'/pyRevit_Command Name_mydata.data'
Universal data files are not cleaned up at pyRevit startup.
Script should manage cleaning up these files.
Args:
file_id (str): unique id for the filename
file_ext (str): file extension
add_cmd_name (bool, optional): add command name to file name
Returns:
(str): full file path
"""
if add_cmd_name:
script_file_id = '{}_{}'.format(EXEC_PARAMS.command_name, file_id)
else:
script_file_id = file_id
return appdata.get_universal_data_file(script_file_id, file_ext)
```` | ### `get_data_file(file_id, file_ext, add_cmd_name=False)` Return filename to be used by a user script to store data. File name is generated in this format: `pyRevit_{Revit Version}_{file_id}.{file_ext}` Examples: ```md-code__content script.get_data_file('mydata', 'data') ``` '/pyRevit\_2018\_mydata.data' ```md-code__content script.get_data_file('mydata', 'data', add_cmd_name=True) ``` '/pyRevit\_2018\_Command Name\_mydata.data' Data files are not cleaned up at pyRevit startup. Script should manage cleaning up these files. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | unique id for the filename | _required_ | | `file_ext` | `str` | file extension | _required_ | | `add_cmd_name` | `bool` | add command name to file name | `False` | Returns: | Type | Description | | --- | --- | | `str` | full file path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
``` | ````md-code__content
def get_data_file(file_id, file_ext, add_cmd_name=False):
"""Return filename to be used by a user script to store data.
File name is generated in this format:
``pyRevit_{Revit Version}_{file_id}.{file_ext}``
Examples:
```python
script.get_data_file('mydata', 'data')
```
'/pyRevit_2018_mydata.data'
```python
script.get_data_file('mydata', 'data', add_cmd_name=True)
```
'/pyRevit_2018_Command Name_mydata.data'
Data files are not cleaned up at pyRevit startup.
Script should manage cleaning up these files.
Args:
file_id (str): unique id for the filename
file_ext (str): file extension
add_cmd_name (bool, optional): add command name to file name
Returns:
(str): full file path
"""
if add_cmd_name:
script_file_id = '{}_{}'.format(EXEC_PARAMS.command_name, file_id)
else:
script_file_id = file_id
return appdata.get_data_file(script_file_id, file_ext)
```` | ### `get_instance_data_file(file_id, add_cmd_name=False)` Return filename to be used by a user script to store data. File name is generated in this format: `pyRevit_{Revit Version}_{Process Id}_{file_id}.{file_ext}` Examples: ```md-code__content script.get_instance_data_file('mydata') ``` '/pyRevit\_2018\_6684\_mydata.tmp' ```md-code__content script.get_instance_data_file('mydata', add_cmd_name=True) ``` '/pyRevit\_2018\_6684\_Command Name\_mydata.tmp' Instance data files are cleaned up at pyRevit startup. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | unique id for the filename | _required_ | | `add_cmd_name` | `bool` | add command name to file name | `False` | Returns: | Type | Description | | --- | --- | | `str` | full file path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
``` | ````md-code__content
def get_instance_data_file(file_id, add_cmd_name=False):
"""Return filename to be used by a user script to store data.
File name is generated in this format:
``pyRevit_{Revit Version}_{Process Id}_{file_id}.{file_ext}``
Examples:
```python
script.get_instance_data_file('mydata')
```
'/pyRevit_2018_6684_mydata.tmp'
```python
script.get_instance_data_file('mydata', add_cmd_name=True)
```
'/pyRevit_2018_6684_Command Name_mydata.tmp'
Instance data files are cleaned up at pyRevit startup.
Args:
file_id (str): unique id for the filename
add_cmd_name (bool, optional): add command name to file name
Returns:
(str): full file path
"""
if add_cmd_name:
script_file_id = '{}_{}'.format(EXEC_PARAMS.command_name, file_id)
else:
script_file_id = file_id
return appdata.get_instance_data_file(script_file_id)
```` | ### `get_document_data_file(file_id, file_ext, add_cmd_name=False)` Return filename to be used by a user script to store data. File name is generated in this format: `pyRevit_{Revit Version}_{file_id}_{Project Name}.{file_ext}` Examples: ```md-code__content script.get_document_data_file('mydata', 'data') ``` '/pyRevit\_2018\_mydata\_Project1.data' ```md-code__content script.get_document_data_file('mydata', 'data', add_cmd_name=True) ``` '/pyRevit\_2018\_Command Name\_mydata\_Project1.data' Document data files are not cleaned up at pyRevit startup. Script should manage cleaning up these files. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | unique id for the filename | _required_ | | `file_ext` | `str` | file extension | _required_ | | `add_cmd_name` | `bool` | add command name to file name | `False` | Returns: | Type | Description | | --- | --- | | `str` | full file path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
``` | ````md-code__content
def get_document_data_file(file_id, file_ext, add_cmd_name=False):
"""Return filename to be used by a user script to store data.
File name is generated in this format:
``pyRevit_{Revit Version}_{file_id}_{Project Name}.{file_ext}``
Examples:
```python
script.get_document_data_file('mydata', 'data')
```
'/pyRevit_2018_mydata_Project1.data'
```python
script.get_document_data_file('mydata', 'data', add_cmd_name=True)
```
'/pyRevit_2018_Command Name_mydata_Project1.data'
Document data files are not cleaned up at pyRevit startup.
Script should manage cleaning up these files.
Args:
file_id (str): unique id for the filename
file_ext (str): file extension
add_cmd_name (bool, optional): add command name to file name
Returns:
(str): full file path
"""
proj_info = revit.query.get_project_info()
if add_cmd_name:
script_file_id = '{}_{}_{}'.format(EXEC_PARAMS.command_name,
file_id,
proj_info.filename
or proj_info.name)
else:
script_file_id = '{}_{}'.format(file_id,
proj_info.filename
or proj_info.name)
return appdata.get_data_file(script_file_id, file_ext)
```` | ### `remove_data_file(filepath)` Remove given data file. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
363
364
365
``` | ```md-code__content
def remove_data_file(filepath):
"""Remove given data file."""
appdata.garbage_data_file(filepath)
``` | ### `get_bundle_file(file_name)` Return full path to file under current script bundle. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_name` | `str` | bundle file name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | full bundle file path | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
368
369
370
371
372
373
374
375
376
377
``` | ```md-code__content
def get_bundle_file(file_name):
"""Return full path to file under current script bundle.
Args:
file_name (str): bundle file name
Returns:
(str): full bundle file path
"""
return op.join(EXEC_PARAMS.command_path, file_name)
``` | ### `get_bundle_files(sub_path=None)` Return full path to all file under current script bundle. Returns: | Type | Description | | --- | --- | | `list[str]` | list of bundle file paths | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
387
388
389
390
``` | ```md-code__content
def get_bundle_files(sub_path=None):
"""Return full path to all file under current script bundle.
Returns:
(list[str]): list of bundle file paths
"""
if sub_path:
command_path = op.join(EXEC_PARAMS.command_path, sub_path)
else:
command_path = EXEC_PARAMS.command_path
return [op.join(command_path, x) for x in os.listdir(command_path)]
``` | ### `journal_write(data_key, msg)` Write key and value to active Revit journal for current command. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `data_key` | `str` | data key | _required_ | | `msg` | `str` | data value string | _required_ | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
393
394
395
396
397
398
399
400
401
402
403
404
405
``` | ```md-code__content
def journal_write(data_key, msg):
"""Write key and value to active Revit journal for current command.
Args:
data_key (str): data key
msg (str): data value string
"""
# Get the StringStringMap class which can write data into.
data_map = EXEC_PARAMS.command_data.JournalData
data_map.Clear()
# Begin to add the support data
data_map.Add(data_key, msg)
``` | ### `journal_read(data_key)` Read value for provided key from active Revit journal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `data_key` | `str` | data key | _required_ | Returns: | Type | Description | | --- | --- | | `str` | data value string | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
408
409
410
411
412
413
414
415
416
417
418
419
420
421
``` | ```md-code__content
def journal_read(data_key):
"""Read value for provided key from active Revit journal.
Args:
data_key (str): data key
Returns:
(str): data value string
"""
# Get the StringStringMap class which can write data into.
data_map = EXEC_PARAMS.command_data.JournalData
# Begin to get the support data
return data_map[data_key]
``` | ### `get_button()` Find and return current script ui button. Returns: | Type | Description | | --- | --- | | `_PyRevitRibbonButton` | ui button object | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
424
425
426
427
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
def get_button():
"""Find and return current script ui button.
Returns:
(pyrevit.coreutils.ribbon._PyRevitRibbonButton): ui button object
"""
from pyrevit.coreutils.ribbon import get_current_ui
pyrvt_tabs = get_current_ui().get_pyrevit_tabs()
for tab in pyrvt_tabs:
button = tab.find_child(EXEC_PARAMS.command_name)
if button:
return button
return None
``` | ### `get_all_buttons()` Find and return all ui buttons matching current script command name. Sometimes tools are duplicated across extensions for user access control so this would help smart buttons to find all the loaded buttons and make icon adjustments. Returns: | Type | Description | | --- | --- | | `list[_PyRevitRibbonButton]` | list of ui button objects | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
``` | ```md-code__content
def get_all_buttons():
"""Find and return all ui buttons matching current script command name.
Sometimes tools are duplicated across extensions for user access control
so this would help smart buttons to find all the loaded buttons and make
icon adjustments.
Returns:
(list[pyrevit.coreutils.ribbon._PyRevitRibbonButton]):
list of ui button objects
"""
from pyrevit.coreutils.ribbon import get_current_ui
pyrvt_tabs = get_current_ui().get_pyrevit_tabs()
buttons = []
for tab in pyrvt_tabs:
button = tab.find_child(EXEC_PARAMS.command_name)
if button:
buttons.append(button)
return buttons
``` | ### `toggle_icon(new_state, on_icon_path=None, off_icon_path=None, icon_size=ICON_MEDIUM)` Set the state of button icon (on or off). This method expects on.png and off.png in command bundle for on and off icon states, unless full path of icon states are provided. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `new_state` | `bool` | state of the ui button icon. | _required_ | | `on_icon_path` | `str` | full path of icon for on state.
default='on.png' | `None` | | `off_icon_path` | `str` | full path of icon for off state.
default='off.png' | `None` | | `icon_size` | `int` | size of the icon. Defaults to medium (24x24) | `ICON_MEDIUM` | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
``` | ```md-code__content
def toggle_icon(new_state, on_icon_path=None, off_icon_path=None, icon_size=ICON_MEDIUM):
"""Set the state of button icon (on or off).
This method expects on.png and off.png in command bundle for on and off
icon states, unless full path of icon states are provided.
Args:
new_state (bool): state of the ui button icon.
on_icon_path (str, optional): full path of icon for on state.
default='on.png'
off_icon_path (str, optional): full path of icon for off state.
default='off.png'
icon_size (int): size of the icon. Defaults to medium (24x24)
"""
# find the ui button
uibuttons = get_all_buttons()
if not uibuttons:
mlogger.debug('Can not find ui button.')
return
# get icon for on state
if not on_icon_path:
on_icon_path = ui.resolve_icon_file(EXEC_PARAMS.command_path, exts.DEFAULT_ON_ICON_FILE)
if not on_icon_path:
mlogger.debug('Script does not have icon for on state.')
return
# get icon for off state
if not off_icon_path:
off_icon_path = ui.resolve_icon_file(EXEC_PARAMS.command_path, exts.DEFAULT_OFF_ICON_FILE)
if not off_icon_path:
mlogger.debug('Script does not have icon for on state.')
return
icon_path = on_icon_path if new_state else off_icon_path
mlogger.debug('Setting icon state to: %s (%s)',
new_state, icon_path)
for uibutton in uibuttons:
uibutton.set_icon(icon_path, icon_size)
``` | ### `exit()` Stop the script execution and exit. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
502
503
504
``` | ```md-code__content
def exit(): #pylint: disable=W0622
"""Stop the script execution and exit."""
sys.exit()
``` | ### `show_file_in_explorer(file_path)` Show file in Windows Explorer. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
507
508
509
``` | ```md-code__content
def show_file_in_explorer(file_path):
"""Show file in Windows Explorer."""
coreutils.show_entry_in_explorer(file_path)
``` | ### `show_folder_in_explorer(folder_path)` Show folder in Windows Explorer. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
512
513
514
``` | ```md-code__content
def show_folder_in_explorer(folder_path):
"""Show folder in Windows Explorer."""
coreutils.open_folder_in_explorer(folder_path)
``` | ### `open_url(url)` Open url in a new tab in default webbrowser. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
517
518
519
520
521
522
523
``` | ```md-code__content
def open_url(url):
"""Open url in a new tab in default webbrowser."""
import webbrowser
if re.match('^https*://', url.lower()):
webbrowser.open_new_tab(url)
else:
webbrowser.open_new_tab('http://' + url)
``` | ### `clipboard_copy(string_to_copy)` Copy string to Windows Clipboard. Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
526
527
528
``` | ```md-code__content
def clipboard_copy(string_to_copy):
"""Copy string to Windows Clipboard."""
framework.Clipboard.SetText(string_to_copy)
``` | ### `load_index(index_file='index.html')` Load html file into output window. This method expects index.html file in the current command bundle, unless full path to an html file is provided. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `index_file` | `str` | full path of html file. | `'index.html'` | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
539
540
541
542
543
``` | ```md-code__content
def load_index(index_file='index.html'):
"""Load html file into output window.
This method expects index.html file in the current command bundle,
unless full path to an html file is provided.
Args:
index_file (str, optional): full path of html file.
"""
outputwindow = get_output()
if not op.isfile(index_file):
index_file = get_bundle_file(index_file)
outputwindow.open_page(index_file)
``` | ### `load_ui(ui_instance, ui_file='ui.xaml', handle_esc=True, set_owner=True)` Load xaml file into given window instance. If window instance defines a method named `setup` it will be called after loading Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `ui_instance` | `WPFWindow` | ui form instance | _required_ | | `ui_file` | `str` | name of ui xaml file. defaults to: 'ui.xaml' | `'ui.xaml'` | | `handle_esc` | `bool` | handle escape and close window | `True` | | `set_owner` | `bool` | set window owner to Revit window | `True` | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
``` | ```md-code__content
def load_ui(ui_instance, ui_file='ui.xaml', handle_esc=True, set_owner=True):
"""Load xaml file into given window instance.
If window instance defines a method named `setup` it
will be called after loading
Args:
ui_instance (forms.WPFWindow): ui form instance
ui_file (str, optional): name of ui xaml file. defaults to: 'ui.xaml'
handle_esc (bool, optional): handle escape and close window
set_owner (bool, optional): set window owner to Revit window
"""
ui_file = get_bundle_file(ui_file)
if ui_file:
ui_instance.load_xaml(
ui_file,
literal_string=False,
handle_esc=handle_esc,
set_owner=set_owner
)
if hasattr(ui_instance, 'setup'):
ui_instance.setup()
return ui_instance
raise PyRevitException("Missing bundle ui file: {}".format(ui_file))
``` | ### `get_envvar(envvar)` Return value of give pyRevit environment variable. The environment variable system is used to retain small values in memory between script runs (e.g. active/inactive state for toggle tools). Do not store large objects in memory using this method. List of currently set environment variables could be sees in pyRevit settings window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `envvar` | `str` | name of environment variable | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | object stored in environment variable | Examples: ```md-code__content script.get_envvar('ToolActiveState') ``` True Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
``` | ````md-code__content
def get_envvar(envvar):
"""Return value of give pyRevit environment variable.
The environment variable system is used to retain small values in memory
between script runs (e.g. active/inactive state for toggle tools). Do not
store large objects in memory using this method. List of currently set
environment variables could be sees in pyRevit settings window.
Args:
envvar (str): name of environment variable
Returns:
(Any): object stored in environment variable
Examples:
```python
script.get_envvar('ToolActiveState')
```
True
"""
return envvars.get_pyrevit_env_var(envvar)
```` | ### `set_envvar(envvar, value)` Set value of give pyRevit environment variable. The environment variable system is used to retain small values in memory between script runs (e.g. active/inactive state for toggle tools). Do not store large objects in memory using this method. List of currently set environment variables could be sees in pyRevit settings window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `envvar` | `str` | name of environment variable | _required_ | | `value` | `any` | value of environment variable | _required_ | Examples: ```md-code__content script.set_envvar('ToolActiveState', False) script.get_envvar('ToolActiveState') ``` False Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
``` | ````md-code__content
def set_envvar(envvar, value):
"""Set value of give pyRevit environment variable.
The environment variable system is used to retain small values in memory
between script runs (e.g. active/inactive state for toggle tools). Do not
store large objects in memory using this method. List of currently set
environment variables could be sees in pyRevit settings window.
Args:
envvar (str): name of environment variable
value (any): value of environment variable
Examples:
```python
script.set_envvar('ToolActiveState', False)
script.get_envvar('ToolActiveState')
```
False
"""
return envvars.set_pyrevit_env_var(envvar, value)
```` | ### `dump_json(data, filepath)` Dumps given data into given json file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `data` | `object` | serializable data to be dumped | _required_ | | `filepath` | `str` | json file path | _required_ | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
618
619
620
621
622
623
624
625
626
627
``` | ```md-code__content
def dump_json(data, filepath):
"""Dumps given data into given json file.
Args:
data (object): serializable data to be dumped
filepath (str): json file path
"""
json_repr = json.dumps(data, indent=4, ensure_ascii=False)
with codecs.open(filepath, 'w', "utf-8") as json_file:
json_file.write(json_repr)
``` | ### `load_json(filepath)` Loads data from given json file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filepath` | `str` | json file path | _required_ | Returns: | Type | Description | | --- | --- | | `object` | deserialized data | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
630
631
632
633
634
635
636
637
638
639
640
``` | ```md-code__content
def load_json(filepath):
"""Loads data from given json file.
Args:
filepath (str): json file path
Returns:
(object): deserialized data
"""
with codecs.open(filepath, 'r', "utf-8") as json_file:
return json.load(json_file)
``` | ### `dump_csv(data, filepath)` Dumps given data into given csv file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `data` | `list[list[str]]` | data to be dumped | _required_ | | `filepath` | `str` | csv file path | _required_ | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
643
644
645
646
647
648
649
650
651
652
``` | ```md-code__content
def dump_csv(data, filepath):
"""Dumps given data into given csv file.
Args:
data (list[list[str]]): data to be dumped
filepath (str): csv file path
"""
with codecs.open(filepath, 'wb', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile, delimiter=',', quotechar='\"')
writer.writerows(data)
``` | ### `load_csv(filepath)` Read lines from given csv file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filepath` | `str` | csv file path | _required_ | Returns: | Type | Description | | --- | --- | | `list[list[str]]` | csv data | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
655
656
657
658
659
660
661
662
663
664
665
``` | ```md-code__content
def load_csv(filepath):
"""Read lines from given csv file.
Args:
filepath (str): csv file path
Returns:
(list[list[str]]): csv data
"""
with codecs.open(filepath, 'rb', encoding='utf-8') as csvfile:
return list(csv.reader(csvfile, delimiter=',', quotechar='\"'))
``` | ### `store_data(slot_name, data, this_project=True)` Wraps python pickle.dump() to easily store data to pyRevit data files. To store native Revit objects, use revit.serialize(). See Example Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `slot_name` | `type` | desc | _required_ | | `data` | `obj` | any pickalable data | _required_ | | `this_project` | `bool` | data belongs to this project only | `True` | Examples: ```md-code__content from pyrevit import revit from pyrevit import script class CustomData(object): def __init__(self, count, element_ids): self._count = count # serializes the Revit native objects self._elmnt_ids = [revit.serialize(x) for x in element_ids] @property def count(self): return self._count @property def element_ids(self): # de-serializes the Revit native objects return [x.deserialize() for x in self._elmnt_ids] mydata = CustomData( count=3, element_ids=[, , ] ) script.store_data("Selected Elements", mydata) ``` Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
``` | ````md-code__content
def store_data(slot_name, data, this_project=True):
"""Wraps python pickle.dump() to easily store data to pyRevit data files.
To store native Revit objects, use revit.serialize(). See Example
Args:
slot_name (type): desc
data (obj): any pickalable data
this_project (bool): data belongs to this project only
Examples:
```python
from pyrevit import revit
from pyrevit import script
class CustomData(object):
def __init__(self, count, element_ids):
self._count = count
# serializes the Revit native objects
self._elmnt_ids = [revit.serialize(x) for x in element_ids]
@property
def count(self):
return self._count
@property
def element_ids(self):
# de-serializes the Revit native objects
return [x.deserialize() for x in self._elmnt_ids]
mydata = CustomData(
count=3,
element_ids=[, , ]
)
script.store_data("Selected Elements", mydata)
```
"""
# for this specific project?
if this_project:
data_file = get_document_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
# for any project file
else:
data_file = get_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
with open(data_file, 'w') as dfile:
pickle.dump(data, dfile)
```` | ### `load_data(slot_name, this_project=True)` Wraps python pickle.load() to easily load data from pyRevit data files. To recover native Revit objects, use revit.deserialize(). See Example Similar to pickle module, the custom data types must be defined in the main scope so the loader can create an instance and return original stored data Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `slot_name` | `type` | desc | _required_ | | `this_project` | `bool` | data belongs to this project only | `True` | Returns: | Type | Description | | --- | --- | | `object` | stored data | Examples: ```md-code__content from pyrevit import revit from pyrevit import script class CustomData(object): def __init__(self, count, element_ids): self._count = count # serializes the Revit native objects self._elmnt_ids = [revit.serialize(x) for x in element_ids] @property def count(self): return self._count @property def element_ids(self): # de-serializes the Revit native objects return [x.deserialize() for x in self._elmnt_ids] mydata = script.load_data("Selected Elements") mydata.element_ids ``` \[, , \] Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
``` | ````md-code__content
def load_data(slot_name, this_project=True):
"""Wraps python pickle.load() to easily load data from pyRevit data files.
To recover native Revit objects, use revit.deserialize(). See Example
Similar to pickle module, the custom data types must be defined in the main
scope so the loader can create an instance and return original stored data
Args:
slot_name (type): desc
this_project (bool): data belongs to this project only
Returns:
(object): stored data
Examples:
```python
from pyrevit import revit
from pyrevit import script
class CustomData(object):
def __init__(self, count, element_ids):
self._count = count
# serializes the Revit native objects
self._elmnt_ids = [revit.serialize(x) for x in element_ids]
@property
def count(self):
return self._count
@property
def element_ids(self):
# de-serializes the Revit native objects
return [x.deserialize() for x in self._elmnt_ids]
mydata = script.load_data("Selected Elements")
mydata.element_ids
```
[, , ]
"""
# for this specific project?
if this_project:
data_file = get_document_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
# for any project file
else:
data_file = get_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
with open(data_file, 'r') as dfile:
return pickle.load(dfile)
```` | ### `data_exists(slot_name, this_project=True)` Checks if data file in a specified slot and for certain project exists. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `slot_name` | `type` | desc | _required_ | | `this_project` | `bool` | data belongs to this project only | `True` | Returns: | Type | Description | | --- | --- | | `bool` | true if the path exists | Source code in `pyrevitlib/pyrevit/script.py` | | | | --- | --- | | ```
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
``` | ```md-code__content
def data_exists(slot_name, this_project=True):
"""Checks if data file in a specified slot and for certain project exists.
Args:
slot_name (type): desc
this_project (bool): data belongs to this project only
Returns:
(bool): true if the path exists
"""
# for this specific project?
if this_project:
data_file = get_document_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
# for any project file
else:
data_file = get_data_file(file_id=slot_name,
file_ext=DATAFEXT,
add_cmd_name=False)
return os.path.exists(data_file)
``` | Back to top ## PyRevit Engine Reference [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/engine/#pyrevit.engine) # engine Access loading engine properties. ## Attributes ### `ScriptExecutor = PyRevitLoader.ScriptExecutor``module-attribute` ### `EnginePrefix = ScriptExecutor.EnginePrefix``module-attribute` ### `EngineVersion = ScriptExecutor.EngineVersion``module-attribute` ### `EnginePath = op.dirname(clr.GetClrType(ScriptExecutor).Assembly.Location)``module-attribute` Back to top ## Interop Features Overview [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/#pyrevit.interop) # interop Interoperability with other applications. Back to top ## Preflight Checks Framework [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/preflight/#pyrevit.preflight) # preflight Preflight checks framework. This framework is designed to automate verification and quality control checks that need to be completed before model is published. The framework works very similarly to `unitchecks` module. All preflight checks are subclassed from a base class and are recognized automatically by the preflight module. Each test case, can perform `setUp()`, `startTest()`, `tearDown()`, and `doCleanups()`. ## Classes ### `PreflightCheck(extension, check_type, script_path)` Bases: `object` Preflight Check. Source code in `pyrevitlib/pyrevit/preflight/__init__.py` | | | | --- | --- | | ```
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
``` | ```md-code__content
def __init__(self, extension, check_type, script_path):
self.check_case = check_type
self.name = getattr(self.check_case, "name", None) \
or _get_check_name(script_path)
self.script_path = script_path
self.extension = extension.name
self.author = getattr(self.check_case, "author", None)
if not self.author:
self.author = "Unknown"
extension_pkg = extpkg.get_ext_package_by_name(extension.name)
if extension_pkg:
self.author = extension_pkg.author
desc_lines = getattr(self.check_case, "__doc__", "").strip().split('\n')
if desc_lines:
self.subtitle = desc_lines[0]
self.description = '\n'.join([x.strip() for x in desc_lines[1:]])
``` | #### Attributes ##### `check_case = check_type``instance-attribute` ##### `name = getattr(self.check_case, 'name', None) or _get_check_name(script_path)``instance-attribute` ##### `script_path = script_path``instance-attribute` ##### `extension = extension.name``instance-attribute` ##### `author = getattr(self.check_case, 'author', None)``instance-attribute` ##### `subtitle = desc_lines[0]``instance-attribute` ##### `description = '\n'.join([x.strip() for x in desc_lines[1:]])``instance-attribute` ## Functions ### `run_preflight_check(check, doc, output)` Run a preflight check. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `check` | `PreflightCheck` | preflight test case object | _required_ | | `doc` | `Document` | Revit document | _required_ | | `output` | `PyRevitOutputWindow` | output window wrapper | _required_ | Source code in `pyrevitlib/pyrevit/preflight/__init__.py` | | | | --- | --- | | ```
59
60
61
62
63
64
65
66
67
68
69
70
71
``` | ```md-code__content
def run_preflight_check(check, doc, output):
"""Run a preflight check.
Args:
check (PreflightCheck): preflight test case object
doc (Document): Revit document
output (pyrevit.output.PyRevitOutputWindow): output window wrapper
"""
check_case = check.check_case()
check_case.setUp(doc=doc, output=output)
check_case.startTest(doc=doc, output=output)
check_case.tearDown(doc=doc, output=output)
check_case.doCleanups(doc=doc, output=output)
``` | ### `get_all_preflight_checks()` Find all the preflight checks in installed extensions. Source code in `pyrevitlib/pyrevit/preflight/__init__.py` | | | | --- | --- | | ```
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def get_all_preflight_checks():
"""Find all the preflight checks in installed extensions."""
preflight_checks = []
# get all installed ui extensions
for ext in extensionmgr.get_installed_ui_extensions():
# find the checks in the extension
for check_script in ext.get_checks():
# load the check source file so all the checks can be extracted
check_mod = \
imp.load_source(_get_check_name(check_script), check_script)
# extract the checks and wrap
for check_type in _grab_test_types(check_mod):
preflight_checks.append(
PreflightCheck(ext, check_type, check_script)
)
return preflight_checks
``` | Back to top ## pyRevit HTTP API [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/routes/#pyrevit.routes) # routes HTTP API framework similar to flask. ## Classes ### `Request(path='/', method='GET', data=None, params=None)` Bases: `object` Request wrapper object. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
22
23
24
25
26
27
``` | ```md-code__content
def __init__(self, path='/', method='GET', data=None, params=None):
self.path = path
self.method = method
self.data = data
self._headers = {}
self._params = params or []
``` | #### Attributes ##### `path = path``instance-attribute` ##### `method = method``instance-attribute` ##### `data = data``instance-attribute` ##### `headers``property` Request headers dict. ##### `params``property` Request parameters. ##### `callback_url``property` Request callback url, if provided in payload. #### Functions ##### `add_header(key, value)` Add new header key:value. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
46
47
48
``` | ```md-code__content
def add_header(self, key, value):
"""Add new header key:value."""
self._headers[key] = value
``` | ### `Response(status=200, data=None, headers=None)` Bases: `object` Response wrapper object. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
53
54
55
56
``` | ```md-code__content
def __init__(self, status=200, data=None, headers=None):
self.status = status
self.data = data
self._headers = headers or {}
``` | #### Attributes ##### `status = status``instance-attribute` ##### `data = data``instance-attribute` ##### `headers``property` Response headers dict. #### Functions ##### `add_header(key, value)` Add new header key:value. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
63
64
65
``` | ```md-code__content
def add_header(self, key, value):
"""Add new header key:value."""
self._headers[key] = value
``` | ### `API(name)` Bases: `object` API root object. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `name` | `str` | URL-safe unique root name of the API | _required_ | Examples: ```md-code__content from pyrevit import routes api = routes.API("pyrevit-core") @api.route('/sessions/', methods=['POST']) def reload_pyrevit(uiapp): new_session_id = sessionmgr.reload_pyrevit() return {"session_id": new_session_id} ``` Source code in `pyrevitlib/pyrevit/routes/__init__.py` | | | | --- | --- | | ```
24
25
``` | ```md-code__content
def __init__(self, name):
self.name = name
``` | #### Attributes ##### `name = name``instance-attribute` #### Functions ##### `route(pattern, methods=['GET'])` Define a new route on this API. Source code in `pyrevitlib/pyrevit/routes/__init__.py` | | | | --- | --- | | ```
27
28
29
30
31
32
33
34
35
36
37
38
``` | ```md-code__content
def route(self, pattern, methods=['GET']):
"""Define a new route on this API."""
def __func_wrapper__(f):
for method in methods:
add_route(
api_name=self.name,
pattern=pattern,
method=method,
handler_func=f
)
return f
return __func_wrapper__
``` | ## Functions ### `init()` Initialize routes. Reset all registered routes and shutdown servers. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
32
33
34
35
36
37
``` | ```md-code__content
def init():
"""Initialize routes. Reset all registered routes and shutdown servers."""
# clear all routes
router.reset_routes()
# stop existing server
deactivate_server()
``` | ### `activate_server()` Activate routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
``` | ```md-code__content
def activate_server():
"""Activate routes server for this host instance."""
routes_server = envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
if not routes_server:
try:
rsinfo = serverinfo.register()
routes_server = \
server.RoutesServer(
host=rsinfo.server_host,
port=rsinfo.server_port
)
routes_server.start()
envvars.set_pyrevit_env_var(envvars.ROUTES_SERVER, routes_server)
return routes_server
except Exception as rs_ex:
serverinfo.unregister()
mlogger.error("Error starting Routes server | %s", str(rs_ex))
``` | ### `deactivate_server()` Deactivate the active routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
59
60
61
62
63
64
65
66
67
68
``` | ```md-code__content
def deactivate_server():
"""Deactivate the active routes server for this host instance."""
routes_server = envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
if routes_server:
try:
routes_server.stop()
envvars.set_pyrevit_env_var(envvars.ROUTES_SERVER, None)
serverinfo.unregister()
except Exception as rs_ex:
mlogger.error("Error stopping Routes server | %s", str(rs_ex))
``` | ### `get_active_server()` Get active routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
71
72
73
``` | ```md-code__content
def get_active_server():
"""Get active routes server for this host instance."""
return envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
``` | ### `make_response(data, status=OK, headers=None)` Create Reponse object with. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
76
77
78
79
80
81
``` | ```md-code__content
def make_response(data, status=OK, headers=None):
"""Create Reponse object with."""
res = Response(status=status, data=data)
for key, value in (headers or {}).items():
res.add_header(key, value)
return res
``` | ### `get_routes(api_name)` Get all registered routes for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
84
85
86
87
88
89
90
``` | ```md-code__content
def get_routes(api_name):
"""Get all registered routes for given API name.
Args:
api_name (str): unique name of the api
"""
return router.get_routes(api_name)
``` | ### `add_route(api_name, pattern, method, handler_func)` Add new route for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | | `pattern` | `str` | route pattern | _required_ | | `method` | `str` | method name | _required_ | | `handler_func` | `function` | route handler function | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
93
94
95
96
97
98
99
100
101
102
``` | ```md-code__content
def add_route(api_name, pattern, method, handler_func):
"""Add new route for given API name.
Args:
api_name (str): unique name of the api
pattern (str): route pattern
method (str): method name
handler_func (function): route handler function
"""
return router.add_route(api_name, pattern, method, handler_func)
``` | ### `remove_route(api_name, pattern, method)` Remove previously registered route for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | | `pattern` | `str` | route pattern | _required_ | | `method` | `str` | method name | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
105
106
107
108
109
110
111
112
113
``` | ```md-code__content
def remove_route(api_name, pattern, method):
"""Remove previously registered route for given API name.
Args:
api_name (str): unique name of the api
pattern (str): route pattern
method (str): method name
"""
return router.remove_route(api_name, pattern, method)
``` | ### `active_routes_api()` Activates routes API. Source code in `pyrevitlib/pyrevit/routes/__init__.py` | | | | --- | --- | | ```
42
43
44
``` | ```md-code__content
def active_routes_api():
"""Activates routes API."""
from pyrevit.routes import api
``` | Back to top ## pyRevit Core Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/#pyrevit.coreutils) # coreutils Misc Helper functions for pyRevit. Examples: ```md-code__content from pyrevit import coreutils coreutils.cleanup_string('some string') ``` ## Attributes ### `DEFAULT_SEPARATOR = ';'``module-attribute` ### `UNICODE_NONPRINTABLE_CHARS = ['\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u200b', '\u200c', '\u200d', '\u200e', '\u200f', '\u2028', '\u2029', '\u202a', '\u202b', '\u202c', '\u202d', '\u202e', '\u202f', '\u205f', '\u2060', '\u2066', '\u2067', '\u2068', '\u2069', '\u206a', '\u206b', '\u206c\u206d', '\u206e', '\u206f']``module-attribute` ### `SPECIAL_CHARS = {' ': '', '~': '', '!': 'EXCLAM', '@': 'AT', '\#': 'SHARP', '$': 'DOLLAR', '%': 'PERCENT', '^': '', '&': 'AND', '*': 'STAR', '+': 'PLUS', ';': '', ':': '', ',': '', '"': '', '{': '', '}': '', '[': '', ']': '', '\\(': '', '\\)': '', '-': 'MINUS', '=': 'EQUALS', '<': '', '>': '', '?': 'QMARK', '.': 'DOT', '_': 'UNDERS', '|': 'VERT', '\\/': '', '\\': ''}``module-attribute` ## Classes ### `Timer()` Bases: `object` Timer class using python native time module. Examples: ```md-code__content timer = Timer() timer.get_time() ``` 12 Initialize and Start Timer. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
64
65
66
``` | ```md-code__content
def __init__(self):
"""Initialize and Start Timer."""
self.start = time.time()
``` | #### Attributes ##### `start = time.time()``instance-attribute` #### Functions ##### `restart()` Restart Timer. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
68
69
70
``` | ```md-code__content
def restart(self):
"""Restart Timer."""
self.start = time.time()
``` | ##### `get_time()` Get Elapsed Time. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
72
73
74
``` | ```md-code__content
def get_time(self):
"""Get Elapsed Time."""
return time.time() - self.start
``` | ### `ScriptFileParser(file_address)` Bases: `object` Parse python script to extract variables and docstrings. Primarily designed to assist pyRevit in determining script configurations but can work for any python script. Examples: ```md-code__content finder = ScriptFileParser('/path/to/coreutils/__init__.py') finder.docstring() ``` "Misc Helper functions for pyRevit." ```md-code__content finder.extract_param('SomeValue', []) ``` \[\] Initialize and read provided python script. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_address` | `str` | python script file path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
95
96
97
98
99
100
101
102
103
104
105
106
``` | ```md-code__content
def __init__(self, file_address):
"""Initialize and read provided python script.
Args:
file_address (str): python script file path
"""
self.ast_tree = None
self.file_addr = file_address
with codecs.open(file_address, 'r', 'utf-8') as source_file:
contents = source_file.read()
if contents:
self.ast_tree = ast.parse(contents)
``` | #### Attributes ##### `ast_tree = None``instance-attribute` ##### `file_addr = file_address``instance-attribute` #### Functions ##### `extract_node_value(node)` Manual extraction of values from node. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
``` | ```md-code__content
def extract_node_value(self, node):
"""Manual extraction of values from node."""
if isinstance(node, ast.Assign):
node_value = node.value
else:
node_value = node
if isinstance(node_value, ast.Num):
return node_value.n
elif PY2 and isinstance(node_value, ast.Name):
return node_value.id
elif PY3 and isinstance(node_value, ast.NameConstant):
return node_value.value
elif isinstance(node_value, ast.Str):
return node_value.s
elif isinstance(node_value, ast.List):
return node_value.elts
elif isinstance(node_value, ast.Dict):
return {self.extract_node_value(k):self.extract_node_value(v)
for k, v in zip(node_value.keys, node_value.values)}
``` | ##### `get_docstring()` Get global docstring. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
129
130
131
132
133
134
``` | ```md-code__content
def get_docstring(self):
"""Get global docstring."""
if self.ast_tree:
doc_str = ast.get_docstring(self.ast_tree)
if doc_str:
return doc_str.decode('utf-8')
``` | ##### `extract_param(param_name, default_value=None)` Find variable and extract its value. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | variable name | _required_ | | `default_value` | `any` | default value to be returned if variable does not exist | `None` | Returns: | Type | Description | | --- | --- | | `Any` | value of the variable or None | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
``` | ```md-code__content
def extract_param(self, param_name, default_value=None):
"""Find variable and extract its value.
Args:
param_name (str): variable name
default_value (any):
default value to be returned if variable does not exist
Returns:
(Any): value of the variable or None
"""
if self.ast_tree:
try:
for node in ast.iter_child_nodes(self.ast_tree):
if isinstance(node, ast.Assign):
for target in node.targets:
if hasattr(target, 'id') \
and target.id == param_name:
return ast.literal_eval(node.value)
except Exception as err:
raise PyRevitException('Error parsing parameter: {} '
'in script file for : {} | {}'
.format(param_name, self.file_addr, err))
return default_value
``` | ### `FileWatcher(filepath)` Bases: `object` Simple file version watcher. This is a simple utility class to look for changes in a file based on its timestamp. Examples: ```md-code__content watcher = FileWatcher('/path/to/file.ext') watcher.has_changed ``` True Initialize and read timestamp of provided file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filepath` | `str` | file path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
176
177
178
179
180
181
182
183
184
``` | ```md-code__content
def __init__(self, filepath):
"""Initialize and read timestamp of provided file.
Args:
filepath (str): file path
"""
self._cached_stamp = 0
self._filepath = filepath
self.update_tstamp()
``` | #### Attributes ##### `has_changed``property` Compare current file timestamp to the cached timestamp. #### Functions ##### `update_tstamp()` Update the cached timestamp for later comparison. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
186
187
188
``` | ```md-code__content
def update_tstamp(self):
"""Update the cached timestamp for later comparison."""
self._cached_stamp = os.stat(self._filepath).st_mtime
``` | ### `SafeDict` Bases: `dict` Dictionary that does not fail on any key. This is a dictionary subclass to help with string formatting with unknown key values. Examples: ```md-code__content string = '{target} {attr} is {color}.' safedict = SafeDict({'target': 'Apple', 'attr': 'Color'}) string.format(safedict) # will not fail with missing 'color' key ``` 'Apple Color is {color}.' ## Functions ### `get_all_subclasses(parent_classes)` Return all subclasses of a python class. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `parent_classes` | `list` | list of python classes | _required_ | Returns: | Type | Description | | --- | --- | | `list` | list of python subclasses | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
``` | ```md-code__content
def get_all_subclasses(parent_classes):
"""Return all subclasses of a python class.
Args:
parent_classes (list): list of python classes
Returns:
(list): list of python subclasses
"""
sub_classes = []
# if super-class, get a list of sub-classes.
# Otherwise use component_class to create objects.
for parent_class in parent_classes:
try:
derived_classes = parent_class.__subclasses__()
if not derived_classes:
sub_classes.append(parent_class)
else:
sub_classes.extend(derived_classes)
except AttributeError:
sub_classes.append(parent_class)
return sub_classes
``` | ### `get_sub_folders(search_folder)` Get a list of all subfolders directly inside provided folder. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `search_folder` | `str` | folder path | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | list of subfolder names | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
240
241
242
243
244
245
246
247
248
249
250
251
252
253
``` | ```md-code__content
def get_sub_folders(search_folder):
"""Get a list of all subfolders directly inside provided folder.
Args:
search_folder (str): folder path
Returns:
(list[str]): list of subfolder names
"""
sub_folders = []
for sub_folder in os.listdir(search_folder):
if op.isdir(op.join(search_folder, sub_folder)):
sub_folders.append(sub_folder)
return sub_folders
``` | ### `verify_directory(folder)` Check if the folder exists and if not create the folder. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `folder` | `str` | path of folder to verify | _required_ | Returns: | Type | Description | | --- | --- | | `str` | path of verified folder, equals to provided folder | Raises: | Type | Description | | --- | --- | | `OSError` | on folder creation error. | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
``` | ```md-code__content
def verify_directory(folder):
"""Check if the folder exists and if not create the folder.
Args:
folder (str): path of folder to verify
Returns:
(str): path of verified folder, equals to provided folder
Raises:
OSError: on folder creation error.
"""
if not op.exists(folder):
try:
os.makedirs(folder)
except OSError as err:
raise err
return folder
``` | ### `join_strings(str_list, separator=DEFAULT_SEPARATOR)` Join strings using provided separator. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `str_list` | `list` | list of string values | _required_ | | `separator` | `str` | single separator character,
defaults to DEFAULT\_SEPARATOR | `DEFAULT_SEPARATOR` | Returns: | Type | Description | | --- | --- | | `str` | joined string | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
``` | ```md-code__content
def join_strings(str_list, separator=DEFAULT_SEPARATOR):
"""Join strings using provided separator.
Args:
str_list (list): list of string values
separator (str): single separator character,
defaults to DEFAULT_SEPARATOR
Returns:
(str): joined string
"""
if str_list:
if any(not isinstance(x, str) for x in str_list):
str_list = [str(x) for x in str_list]
return separator.join(str_list)
return ''
``` | ### `cleanup_string(input_str, skip=None)` Replace special characters in string with another string. This function was created to help cleanup pyRevit command unique names from any special characters so C# class names can be created based on those unique names. `coreutils.SPECIAL_CHARS` is the conversion table for this function. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_str` | `str` | input string to be cleaned | _required_ | | `skip` | `Container[str]` | special characters to keep | `None` | Examples: ```md-code__content src_str = 'TEST@Some*' cleanup_string(src_str) ``` "TESTATSomeSTARvalue" Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ````md-code__content
def cleanup_string(input_str, skip=None):
"""Replace special characters in string with another string.
This function was created to help cleanup pyRevit command unique names from
any special characters so C# class names can be created based on those
unique names.
``coreutils.SPECIAL_CHARS`` is the conversion table for this function.
Args:
input_str (str): input string to be cleaned
skip (Container[str]): special characters to keep
Examples:
```python
src_str = 'TEST@Some*'
cleanup_string(src_str)
```
"TESTATSomeSTARvalue"
"""
# remove spaces and special characters from strings
for char, repl in SPECIAL_CHARS.items():
if skip and char in skip:
continue
input_str = input_str.replace(char, repl)
return input_str
```` | ### `get_revit_instance_count()` Return number of open host app instances. Returns: | Type | Description | | --- | --- | | `int` | number of open host app instances. | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
347
348
349
350
351
352
353
``` | ```md-code__content
def get_revit_instance_count():
"""Return number of open host app instances.
Returns:
(int): number of open host app instances.
"""
return len(list(framework.Process.GetProcessesByName(HOST_APP.proc_name)))
``` | ### `run_process(proc, cwd='C:')` Run shell process silently. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `proc` | `str` | process executive name | _required_ | | `cwd` | `str` | current working directory | `'C:'` | Exmaple ```md-code__content run_process('notepad.exe', 'c:/') ``` Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
``` | ````md-code__content
def run_process(proc, cwd='C:'):
"""Run shell process silently.
Args:
proc (str): process executive name
cwd (str): current working directory
Exmaple:
```python
run_process('notepad.exe', 'c:/')
```
"""
import subprocess
return subprocess.Popen(proc,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
cwd=cwd, shell=True)
```` | ### `inspect_calling_scope_local_var(variable_name)` Trace back the stack to find the variable in the caller local stack. PyRevitLoader defines **revit** in builtins and **window** in locals. Thus, modules have access to **revit** but not to **window**. This function is used to find **window** in the caller stack. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `variable_name` | `str` | variable name to look up in caller local scope | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
``` | ```md-code__content
def inspect_calling_scope_local_var(variable_name):
"""Trace back the stack to find the variable in the caller local stack.
PyRevitLoader defines __revit__ in builtins and __window__ in locals.
Thus, modules have access to __revit__ but not to __window__.
This function is used to find __window__ in the caller stack.
Args:
variable_name (str): variable name to look up in caller local scope
"""
import inspect
frame = inspect.stack()[1][0]
while variable_name not in frame.f_locals:
frame = frame.f_back
if frame is None:
return None
return frame.f_locals[variable_name]
``` | ### `inspect_calling_scope_global_var(variable_name)` Trace back the stack to find the variable in the caller global stack. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `variable_name` | `str` | variable name to look up in caller global scope | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
394
395
396
397
398
399
400
401
402
403
404
405
406
407
``` | ```md-code__content
def inspect_calling_scope_global_var(variable_name):
"""Trace back the stack to find the variable in the caller global stack.
Args:
variable_name (str): variable name to look up in caller global scope
"""
import inspect
frame = inspect.stack()[1][0]
while variable_name not in frame.f_globals:
frame = frame.f_back
if frame is None:
return None
return frame.f_locals[variable_name]
``` | ### `make_canonical_name(*args)` Join arguments with dot creating a unique id. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*args` | `str` | Variable length argument list | `()` | Returns: | Type | Description | | --- | --- | | `str` | dot separated unique name | Examples: ```md-code__content make_canonical_name('somename', 'someid', 'txt') ``` "somename.someid.txt" Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
``` | ````md-code__content
def make_canonical_name(*args):
"""Join arguments with dot creating a unique id.
Args:
*args (str): Variable length argument list
Returns:
(str): dot separated unique name
Examples:
```python
make_canonical_name('somename', 'someid', 'txt')
```
"somename.someid.txt"
"""
return '.'.join(args)
```` | ### `get_canonical_parts(canonical_string)` Splots argument using dot, returning all composing parts. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `canonical_string` | `str` | Source string e.g. "Config.SubConfig" | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | list of composing parts | Examples: ```md-code__content get_canonical_parts("Config.SubConfig") ``` \['Config', 'SubConfig'\] Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
``` | ````md-code__content
def get_canonical_parts(canonical_string):
"""Splots argument using dot, returning all composing parts.
Args:
canonical_string (str): Source string e.g. "Config.SubConfig"
Returns:
(list[str]): list of composing parts
Examples:
```python
get_canonical_parts("Config.SubConfig")
```
['Config', 'SubConfig']
"""
return canonical_string.split('.')
```` | ### `get_file_name(file_path)` Return file basename of the given file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_path` | `str` | file path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
446
447
448
449
450
451
452
``` | ```md-code__content
def get_file_name(file_path):
"""Return file basename of the given file.
Args:
file_path (str): file path
"""
return op.splitext(op.basename(file_path))[0]
``` | ### `get_str_hash(source_str)` Calculate hash value of given string. Current implementation uses :func: `hashlib.md5` hash function. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source_str` | `str` | source str | _required_ | Returns: | Type | Description | | --- | --- | | `str` | hash value as string | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
455
456
457
458
459
460
461
462
463
464
465
466
``` | ```md-code__content
def get_str_hash(source_str):
"""Calculate hash value of given string.
Current implementation uses :func:`hashlib.md5` hash function.
Args:
source_str (str): source str
Returns:
(str): hash value as string
"""
return hashlib.md5(source_str.encode('utf-8', 'ignore')).hexdigest()
``` | ### `calculate_dir_hash(dir_path, dir_filter, file_filter)` Create a unique hash to represent state of directory. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dir_path` | `str` | target directory | _required_ | | `dir_filter` | `str` | exclude directories matching this regex | _required_ | | `file_filter` | `str` | exclude files matching this regex | _required_ | Returns: | Type | Description | | --- | --- | | `str` | hash value as string | Examples: ```md-code__content calculate_dir_hash(source_path, '\.extension', '\.json') ``` "1a885a0cae99f53d6088b9f7cee3bf4d" Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
``` | ````md-code__content
def calculate_dir_hash(dir_path, dir_filter, file_filter):
r"""Create a unique hash to represent state of directory.
Args:
dir_path (str): target directory
dir_filter (str): exclude directories matching this regex
file_filter (str): exclude files matching this regex
Returns:
(str): hash value as string
Examples:
```python
calculate_dir_hash(source_path, '\.extension', '\.json')
```
"1a885a0cae99f53d6088b9f7cee3bf4d"
"""
mtime_sum = 0
for root, dirs, files in os.walk(dir_path): #pylint: disable=W0612
if re.search(dir_filter, op.basename(root), flags=re.IGNORECASE):
mtime_sum += op.getmtime(root)
for filename in files:
if re.search(file_filter, filename, flags=re.IGNORECASE):
modtime = op.getmtime(op.join(root, filename))
mtime_sum += modtime
return get_str_hash(safe_strtype(mtime_sum))
```` | ### `prepare_html_str(input_string)` Reformat html string and prepare for pyRevit output window. pyRevit output window renders html content. But this means that < and > characters in outputs from python (e.g. ) will be treated as html tags. To avoid this, all <> characters that are defining html content need to be replaced with special phrases. pyRevit output later translates these phrases back in to < and >. That is how pyRevit distinquishes between <> printed from python and <> that define html. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_string` | `str` | input html string | _required_ | Examples: ```md-code__content prepare_html_str('

Some text

') ``` "&clt;p&cgt;Some text&clt;/p&cgt;" Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
``` | ````md-code__content
def prepare_html_str(input_string):
"""Reformat html string and prepare for pyRevit output window.
pyRevit output window renders html content. But this means that < and >
characters in outputs from python (e.g. ) will be treated
as html tags. To avoid this, all <> characters that are defining
html content need to be replaced with special phrases. pyRevit output
later translates these phrases back in to < and >. That is how pyRevit
distinquishes between <> printed from python and <> that define html.
Args:
input_string (str): input html string
Examples:
```python
prepare_html_str('

Some text

')
```
"&clt;p&cgt;Some text&clt;/p&cgt;"
"""
return input_string.replace('<', '&clt;').replace('>', '&cgt;')
```` | ### `reverse_html(input_html)` Reformat codified pyRevit output html string back to normal html. pyRevit output window renders html content. But this means that < and > characters in outputs from python (e.g. ) will be treated as html tags. To avoid this, all <> characters that are defining html content need to be replaced with special phrases. pyRevit output later translates these phrases back in to < and >. That is how pyRevit distinquishes between <> printed from python and <> that define html. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_html` | `str` | input codified html string | _required_ | Examples: ```md-code__content prepare_html_str('&clt;p&cgt;Some text&clt;/p&cgt;') ``` " Some text " Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
``` | ````md-code__content
def reverse_html(input_html):
"""Reformat codified pyRevit output html string back to normal html.
pyRevit output window renders html content. But this means that < and >
characters in outputs from python (e.g. ) will be treated
as html tags. To avoid this, all <> characters that are defining
html content need to be replaced with special phrases. pyRevit output
later translates these phrases back in to < and >. That is how pyRevit
distinquishes between <> printed from python and <> that define html.
Args:
input_html (str): input codified html string
Examples:
```python
prepare_html_str('&clt;p&cgt;Some text&clt;/p&cgt;')
```
"

Some text

"
"""
return input_html.replace('&clt;', '<').replace('&cgt;', '>')
```` | ### `escape_for_html(input_string)` Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
541
542
``` | ```md-code__content
def escape_for_html(input_string):
return input_string.replace('<', '<').replace('>', '>')
``` | ### `read_url(url_to_open)` Get the url and return response. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `url_to_open` | `str` | url to check access for | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
545
546
547
548
549
550
551
552
``` | ```md-code__content
def read_url(url_to_open):
"""Get the url and return response.
Args:
url_to_open (str): url to check access for
"""
client = framework.WebClient()
return client.DownloadString(url_to_open)
``` | ### `touch(fname, times=None)` Update the timestamp on the given file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `fname` | `str` | target file path | _required_ | | `times` | `int` | number of times to touch the file | `None` | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
555
556
557
558
559
560
561
562
563
``` | ```md-code__content
def touch(fname, times=None):
"""Update the timestamp on the given file.
Args:
fname (str): target file path
times (int): number of times to touch the file
"""
with open(fname, 'a'):
os.utime(fname, times)
``` | ### `read_source_file(source_file_path)` Read text file and return contents. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source_file_path` | `str` | target file path | _required_ | Returns: | Type | Description | | --- | --- | | `str` | file contents | Raises: | Type | Description | | --- | --- | | `PyRevitException` | on read error | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
``` | ```md-code__content
def read_source_file(source_file_path):
"""Read text file and return contents.
Args:
source_file_path (str): target file path
Returns:
(str): file contents
Raises:
PyRevitException: on read error
"""
try:
with open(source_file_path, 'r') as code_file:
return code_file.read()
except Exception as read_err:
raise PyRevitException('Error reading source file: {} | {}'
.format(source_file_path, read_err))
``` | ### `open_folder_in_explorer(folder_path)` Open given folder in Windows Explorer. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `folder_path` | `str` | directory path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
586
587
588
589
590
591
592
593
594
``` | ```md-code__content
def open_folder_in_explorer(folder_path):
"""Open given folder in Windows Explorer.
Args:
folder_path (str): directory path
"""
import subprocess
subprocess.Popen(r'explorer /open,"{}"'
.format(os.path.normpath(folder_path)))
``` | ### `show_entry_in_explorer(entry_path)` Show given entry in Windows Explorer. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `entry_path` | `str` | directory or file path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
597
598
599
600
601
602
603
604
605
``` | ```md-code__content
def show_entry_in_explorer(entry_path):
"""Show given entry in Windows Explorer.
Args:
entry_path (str): directory or file path
"""
import subprocess
subprocess.Popen(r'explorer /select,"{}"'
.format(os.path.normpath(entry_path)))
``` | ### `fully_remove_dir(dir_path)` Remove directory recursively. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dir_path` | `str` | directory path | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
608
609
610
611
612
613
614
615
616
617
618
619
``` | ```md-code__content
def fully_remove_dir(dir_path):
"""Remove directory recursively.
Args:
dir_path (str): directory path
"""
def del_rw(action, name, exc): #pylint: disable=W0613
"""Force delete entry."""
os.chmod(name, stat.S_IWRITE)
os.remove(name)
shutil.rmtree(dir_path, onerror=del_rw)
``` | ### `cleanup_filename(file_name, windows_safe=False)` Cleanup file name from special characters. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_name` | `str` | file name | _required_ | | `windows_safe` | `bool` | whether to use windows safe characters | `False` | Returns: | Type | Description | | --- | --- | | `str` | cleaned up file name | Examples: ```md-code__content cleanup_filename('Myfile-(3).txt') ``` "Myfile(3).txt" ```md-code__content cleanup_filename('Perforations 1/8" (New)') ``` "Perforations 18 (New).txt" Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
``` | ````md-code__content
def cleanup_filename(file_name, windows_safe=False):
"""Cleanup file name from special characters.
Args:
file_name (str): file name
windows_safe (bool): whether to use windows safe characters
Returns:
(str): cleaned up file name
Examples:
```python
cleanup_filename('Myfile-(3).txt')
```
"Myfile(3).txt"
```python
cleanup_filename('Perforations 1/8" (New)')
```
"Perforations 18 (New).txt"
"""
if windows_safe:
return re.sub(r'[\/:*?"<>|]', '', file_name)
else:
return re.sub(r'[^\w_.() -#]|["]', '', file_name)
```` | ### `increment_str(input_str, step=1, expand=False)` Incremenet identifier. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_str` | `str` | identifier e.g. A310a | _required_ | | `step` | `int` | number of steps to change the identifier | `1` | | `expand` | `bool` | removes leading zeroes and duplicate letters | `False` | Returns: | Type | Description | | --- | --- | | `str` | modified identifier | Examples: ```md-code__content increment_str('A319z') ``` 'A320a' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
``` | ````md-code__content
def increment_str(input_str, step=1, expand=False):
"""Incremenet identifier.
Args:
input_str (str): identifier e.g. A310a
step (int): number of steps to change the identifier
expand (bool): removes leading zeroes and duplicate letters
Returns:
(str): modified identifier
Examples:
```python
increment_str('A319z')
```
'A320a'
"""
return _inc_or_dec_string(input_str, abs(step), refit=expand)
```` | ### `decrement_str(input_str, step=1, shrink=False)` Decrement identifier. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_str` | `str` | identifier e.g. A310a | _required_ | | `step` | `int` | number of steps to change the identifier | `1` | | `shrink` | `bool` | removes leading zeroes or duplicate letters | `False` | Returns: | Type | Description | | --- | --- | | `str` | modified identifier | Examples: ```md-code__content decrement_str('A310a') ``` 'A309z' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
``` | ````md-code__content
def decrement_str(input_str, step=1, shrink=False):
"""Decrement identifier.
Args:
input_str (str): identifier e.g. A310a
step (int): number of steps to change the identifier
shrink (bool): removes leading zeroes or duplicate letters
Returns:
(str): modified identifier
Examples:
```python
decrement_str('A310a')
```
'A309z'
"""
return _inc_or_dec_string(input_str, -abs(step), refit=shrink)
```` | ### `extend_counter(input_str, upper=True, use_zero=False)` Add a new level to identifier. e.g. A310 -> A310A. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_str` | `str` | identifier e.g. A310 | _required_ | | `upper` | `bool` | use UPPERCASE characters for extension | `True` | | `use_zero` | `bool` | start from 0 for numeric extension | `False` | Returns: | Type | Description | | --- | --- | | `str` | extended identifier | Examples: ```md-code__content extend_counter('A310') ``` 'A310A' ```md-code__content extend_counter('A310A', use_zero=True) ``` 'A310A0' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
``` | ````md-code__content
def extend_counter(input_str, upper=True, use_zero=False):
"""Add a new level to identifier. e.g. A310 -> A310A.
Args:
input_str (str): identifier e.g. A310
upper (bool): use UPPERCASE characters for extension
use_zero (bool): start from 0 for numeric extension
Returns:
(str): extended identifier
Examples:
```python
extend_counter('A310')
```
'A310A'
```python
extend_counter('A310A', use_zero=True)
```
'A310A0'
"""
if input_str[-1].isdigit():
return input_str + ("A" if upper else "a")
else:
return input_str + ("0" if use_zero else "1")
```` | ### `filter_null_items(src_list)` Remove None items in the given list. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `src_list` | `list[Any]` | list of any items | _required_ | Returns: | Type | Description | | --- | --- | | `list[Any]` | cleaned list | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
821
822
823
824
825
826
827
828
829
830
``` | ```md-code__content
def filter_null_items(src_list):
"""Remove None items in the given list.
Args:
src_list (list[Any]): list of any items
Returns:
(list[Any]): cleaned list
"""
return list(filter(bool, src_list))
``` | ### `reverse_dict(input_dict)` Reverse the key, value pairs. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_dict` | `dict` | source ordered dict | _required_ | Returns: | Type | Description | | --- | --- | | `defaultdict` | reversed dictionary | Examples: ```md-code__content reverse_dict({1: 2, 3: 4}) ``` defaultdict(, {2: \[1\], 4: \[3\]}) Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
``` | ````md-code__content
def reverse_dict(input_dict):
"""Reverse the key, value pairs.
Args:
input_dict (dict): source ordered dict
Returns:
(defaultdict): reversed dictionary
Examples:
```python
reverse_dict({1: 2, 3: 4})
```
defaultdict(, {2: [1], 4: [3]})
"""
output_dict = defaultdict(list)
for key, value in input_dict.items():
output_dict[value].append(key)
return output_dict
```` | ### `timestamp()` Return timestamp for current time. Returns: | Type | Description | | --- | --- | | `str` | timestamp in string format | Examples: ```md-code__content timestamp() ``` '01003075032506808' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
854
855
856
857
858
859
860
861
862
863
864
865
866
``` | ````md-code__content
def timestamp():
"""Return timestamp for current time.
Returns:
(str): timestamp in string format
Examples:
```python
timestamp()
```
'01003075032506808'
"""
return datetime.datetime.now().strftime("%m%j%H%M%S%f")
```` | ### `current_time()` Return formatted current time. Current implementation uses %H:%M:%S to format time. Returns: | Type | Description | | --- | --- | | `str` | formatted current time. | Examples: ```md-code__content current_time() ``` '07:50:53' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
``` | ````md-code__content
def current_time():
"""Return formatted current time.
Current implementation uses %H:%M:%S to format time.
Returns:
(str): formatted current time.
Examples:
```python
current_time()
```
'07:50:53'
"""
return datetime.datetime.now().strftime("%H:%M:%S")
```` | ### `current_date()` Return formatted current date. Current implementation uses %Y-%m-%d to format date. Returns: | Type | Description | | --- | --- | | `str` | formatted current date. | Examples: ```md-code__content current_date() ``` '2018-01-03' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
``` | ````md-code__content
def current_date():
"""Return formatted current date.
Current implementation uses %Y-%m-%d to format date.
Returns:
(str): formatted current date.
Examples:
```python
current_date()
```
'2018-01-03'
"""
return datetime.datetime.now().strftime("%Y-%m-%d")
```` | ### `is_blank(input_string)` Check if input string is blank (multiple white spaces is blank). Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_string` | `str` | input string | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if string is blank | Examples: ```md-code__content is_blank(' ') ``` True Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
``` | ````md-code__content
def is_blank(input_string):
"""Check if input string is blank (multiple white spaces is blank).
Args:
input_string (str): input string
Returns:
(bool): True if string is blank
Examples:
```python
is_blank(' ')
```
True
"""
if input_string and input_string.strip():
return False
return True
```` | ### `is_url_valid(url_string)` Check if given URL is in valid format. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `url_string` | `str` | URL string | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if URL is in valid format | Examples: ```md-code__content is_url_valid('https://www.google.com') ``` True Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
``` | ````md-code__content
def is_url_valid(url_string):
"""Check if given URL is in valid format.
Args:
url_string (str): URL string
Returns:
(bool): True if URL is in valid format
Examples:
```python
is_url_valid('https://www.google.com')
```
True
"""
regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+'
r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...
r'localhost|' # localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
return regex.match(url_string)
```` | ### `reformat_string(orig_str, orig_format, new_format)` Reformat a string into a new format. Extracts information from a string based on a given pattern, and recreates a new string based on the given new pattern. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `orig_str` | `str` | Original string to be reformatted | _required_ | | `orig_format` | `str` | Pattern of the original str (data to be extracted) | _required_ | | `new_format` | `str` | New pattern (how to recompose the data) | _required_ | Returns: | Type | Description | | --- | --- | | `str` | Reformatted string | Examples: ```md-code__content reformat_string('150 - FLOOR/CEILING - WD - 1 HR - FLOOR ASSEMBLY', '{section} - {loc} - {mat} - {rating} - {name}', '{section}:{mat}:{rating} - {name} ({loc})')) ``` '150:WD:1 HR - FLOOR ASSEMBLY (FLOOR/CEILING)' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
``` | ````md-code__content
def reformat_string(orig_str, orig_format, new_format):
"""Reformat a string into a new format.
Extracts information from a string based on a given pattern,
and recreates a new string based on the given new pattern.
Args:
orig_str (str): Original string to be reformatted
orig_format (str): Pattern of the original str (data to be extracted)
new_format (str): New pattern (how to recompose the data)
Returns:
(str): Reformatted string
Examples:
```python
reformat_string('150 - FLOOR/CEILING - WD - 1 HR - FLOOR ASSEMBLY',
'{section} - {loc} - {mat} - {rating} - {name}',
'{section}:{mat}:{rating} - {name} ({loc})'))
```
'150:WD:1 HR - FLOOR ASSEMBLY (FLOOR/CEILING)'
"""
# find the tags
tag_extractor = re.compile('{(.+?)}')
tags = tag_extractor.findall(orig_format)
# replace the tags with regex patterns
# to create a regex pattern that finds values
tag_replacer = re.compile('{.+?}')
value_extractor_pattern = tag_replacer.sub('(.+)', orig_format)
# find all values
value_extractor = re.compile(value_extractor_pattern)
match = value_extractor.match(orig_str)
values = match.groups()
# create a dictionary of tags and values
reformat_dict = {}
for key, value in zip(tags, values):
reformat_dict[key] = value
# use dictionary to reformat the string into new
return new_format.format(**reformat_dict)
```` | ### `get_mapped_drives_dict()` Return a dictionary of currently mapped network drives. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
994
995
996
997
998
999
1000
1001
``` | ```md-code__content
def get_mapped_drives_dict():
"""Return a dictionary of currently mapped network drives."""
searcher = framework.ManagementObjectSearcher(
"root\\CIMV2",
"SELECT * FROM Win32_MappedLogicalDisk"
)
return {x['DeviceID']: x['ProviderName'] for x in searcher.Get()}
``` | ### `dletter_to_unc(dletter_path)` Convert drive letter path into UNC path of that drive. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dletter_path` | `str` | drive letter path | _required_ | Returns: | Type | Description | | --- | --- | | `str` | UNC path | Examples: ```md-code__content # assuming J: is mapped to //filestore/server/jdrive dletter_to_unc('J:/somefile.txt') ``` '//filestore/server/jdrive/somefile.txt' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
``` | ````md-code__content
def dletter_to_unc(dletter_path):
"""Convert drive letter path into UNC path of that drive.
Args:
dletter_path (str): drive letter path
Returns:
(str): UNC path
Examples:
```python
# assuming J: is mapped to //filestore/server/jdrive
dletter_to_unc('J:/somefile.txt')
```
'//filestore/server/jdrive/somefile.txt'
"""
drives = get_mapped_drives_dict()
dletter = dletter_path[:2]
for mapped_drive, server_path in drives.items():
if dletter.lower() == mapped_drive.lower():
return dletter_path.replace(dletter, server_path)
```` | ### `unc_to_dletter(unc_path)` Convert UNC path into drive letter path. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `unc_path` | `str` | UNC path | _required_ | Returns: | Type | Description | | --- | --- | | `str` | drive letter path | Examples: ```md-code__content # assuming J: is mapped to //filestore/server/jdrive unc_to_dletter('//filestore/server/jdrive/somefile.txt') ``` 'J:/somefile.txt' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
``` | ````md-code__content
def unc_to_dletter(unc_path):
"""Convert UNC path into drive letter path.
Args:
unc_path (str): UNC path
Returns:
(str): drive letter path
Examples:
```python
# assuming J: is mapped to //filestore/server/jdrive
unc_to_dletter('//filestore/server/jdrive/somefile.txt')
```
'J:/somefile.txt'
"""
drives = get_mapped_drives_dict()
for mapped_drive, server_path in drives.items():
if server_path in unc_path:
return unc_path.replace(server_path, mapped_drive)
```` | ### `random_color()` Return a random color channel value (between 0 and 255). Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1049
1050
1051
``` | ```md-code__content
def random_color():
"""Return a random color channel value (between 0 and 255)."""
return random.randint(0, 255)
``` | ### `random_alpha()` Return a random alpha value (between 0 and 1.00). Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1054
1055
1056
``` | ```md-code__content
def random_alpha():
"""Return a random alpha value (between 0 and 1.00)."""
return round(random.random(), 2)
``` | ### `random_hex_color()` Return a random color in hex format. Examples: ```md-code__content random_hex_color() ``` '#FF0000' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
``` | ````md-code__content
def random_hex_color():
"""Return a random color in hex format.
Examples:
```python
random_hex_color()
```
'#FF0000'
"""
return '#%02X%02X%02X' % (random_color(),
random_color(),
random_color())
```` | ### `random_rgb_color()` Return a random color in rgb format. Examples: ```md-code__content random_rgb_color() ``` 'rgb(255, 0, 0)' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
``` | ````md-code__content
def random_rgb_color():
"""Return a random color in rgb format.
Examples:
```python
random_rgb_color()
```
'rgb(255, 0, 0)'
"""
return 'rgb(%d, %d, %d)' % (random_color(),
random_color(),
random_color())
```` | ### `random_rgba_color()` Return a random color in rgba format. Examples: ```md-code__content random_rgba_color() ``` 'rgba(255, 0, 0, 0.5)' Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
``` | ````md-code__content
def random_rgba_color():
"""Return a random color in rgba format.
Examples:
```python
random_rgba_color()
```
'rgba(255, 0, 0, 0.5)'
"""
return 'rgba(%d, %d, %d, %.2f)' % (random_color(),
random_color(),
random_color(),
random_alpha())
```` | ### `extract_range(formatted_str, max_range=500)` Extract range from formatted string. String must be formatted as below A103 No range A103-A106 A103 to A106 A103:A106 A103 to A106 A103,A105a A103 and A105a A103;A105a A103 and A105a Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `formatted_str` | `str` | string specifying range | _required_ | | `max_range` | `int` | maximum number of items to create. | `500` | Returns: | Type | Description | | --- | --- | | `list[str]` | names in the specified range | Examples: ```md-code__content exract_range('A103:A106') ``` \['A103', 'A104', 'A105', 'A106'\] ```md-code__content exract_range('S203-S206') ``` \['S203', 'S204', 'S205', 'S206'\] ```md-code__content exract_range('M00A,M00B') ``` \['M00A', 'M00B'\] Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
``` | ````md-code__content
def extract_range(formatted_str, max_range=500):
"""Extract range from formatted string.
String must be formatted as below
A103 No range
A103-A106 A103 to A106
A103:A106 A103 to A106
A103,A105a A103 and A105a
A103;A105a A103 and A105a
Args:
formatted_str (str): string specifying range
max_range (int): maximum number of items to create.
Returns:
(list[str]): names in the specified range
Examples:
```python
exract_range('A103:A106')
```
['A103', 'A104', 'A105', 'A106']
```python
exract_range('S203-S206')
```
['S203', 'S204', 'S205', 'S206']
```python
exract_range('M00A,M00B')
```
['M00A', 'M00B']
"""
for rchar, rchartype in {'::': 'range', '--': 'range',
',': 'list', ';': 'list'}.items():
if rchar in formatted_str:
if rchartype == 'range' \
and formatted_str.count(rchar) == 1:
items = []
start, end = formatted_str.split(rchar)
assert len(start) == len(end), \
'Range start and end must have same length'
items.append(start)
item = increment_str(start, 1)
safe_counter = 0
while item != end:
items.append(item)
item = increment_str(item, 1)
safe_counter += 1
assert safe_counter < max_range, 'Max range reached.'
items.append(end)
return items
elif rchartype == 'list':
return [x.strip() for x in formatted_str.split(rchar)]
return [formatted_str]
```` | ### `check_encoding_bom(filename, bom_bytes=codecs.BOM_UTF8)` Check if given file contains the given BOM bytes at the start. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filename` | `str` | file path | _required_ | | `bom_bytes` | `bytes` | BOM bytes to check | `BOM_UTF8` | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1157
1158
1159
1160
1161
1162
1163
1164
1165
``` | ```md-code__content
def check_encoding_bom(filename, bom_bytes=codecs.BOM_UTF8):
"""Check if given file contains the given BOM bytes at the start.
Args:
filename (str): file path
bom_bytes (bytes, optional): BOM bytes to check
"""
with open(filename, 'rb') as rtfile:
return rtfile.read()[:len(bom_bytes)] == bom_bytes
``` | ### `has_nonprintable(input_str)` Check input string for non-printable characters. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_str` | `str` | input string | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if contains non-printable characters | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
``` | ```md-code__content
def has_nonprintable(input_str):
"""Check input string for non-printable characters.
Args:
input_str (str): input string
Returns:
(bool): True if contains non-printable characters
"""
return any([x in input_str for x in UNICODE_NONPRINTABLE_CHARS])
``` | ### `get_enum_values(enum_type)` Returns enum values. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1180
1181
1182
``` | ```md-code__content
def get_enum_values(enum_type):
"""Returns enum values."""
return framework.Enum.GetValues(enum_type)
``` | ### `get_enum_value(enum_type, value_string)` Return enum value matching given value string (case insensitive). Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1185
1186
1187
1188
1189
``` | ```md-code__content
def get_enum_value(enum_type, value_string):
"""Return enum value matching given value string (case insensitive)."""
for ftype in get_enum_values(enum_type):
if str(ftype).lower() == value_string.lower():
return ftype
``` | ### `get_enum_none(enum_type)` Returns the None value in given Enum. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1192
1193
1194
1195
1196
``` | ```md-code__content
def get_enum_none(enum_type):
"""Returns the None value in given Enum."""
for val in get_enum_values(enum_type):
if str(val) == 'None':
return val
``` | ### `extract_guid(source_str)` Extract GUID number from a string. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1199
1200
1201
1202
1203
1204
1205
1206
1207
``` | ```md-code__content
def extract_guid(source_str):
"""Extract GUID number from a string."""
guid_match = re.match(".*([0-9A-Fa-f]{8}"
"[-][0-9A-Fa-f]{4}"
"[-][0-9A-Fa-f]{4}"
"[-][0-9A-Fa-f]{4}"
"[-][0-9A-Fa-f]{12}).*", source_str)
if guid_match:
return guid_match.groups()[0]
``` | ### `format_hex_rgb(rgb_value)` Formats rgb value as #RGB value string. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1210
1211
1212
1213
1214
1215
1216
1217
1218
``` | ```md-code__content
def format_hex_rgb(rgb_value):
"""Formats rgb value as #RGB value string."""
if isinstance(rgb_value, str):
if not rgb_value.startswith('#'):
return '#%s' % rgb_value
else:
return rgb_value
elif isinstance(rgb_value, int):
return '#%x' % rgb_value
``` | ### `new_uuid()` Create a new UUID (using dotnet Guid.NewGuid). Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1221
1222
1223
1224
1225
``` | ```md-code__content
def new_uuid():
"""Create a new UUID (using dotnet Guid.NewGuid)."""
# RE: https://github.com/pyrevitlabs/pyRevit/issues/413
# return uuid.uuid1()
return str(Guid.NewGuid())
``` | ### `is_box_visible_on_screens(left, top, width, height)` Check if given box is visible on any screen. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
``` | ```md-code__content
def is_box_visible_on_screens(left, top, width, height):
"""Check if given box is visible on any screen."""
bounds = \
framework.Drawing.Rectangle(
framework.Convert.ToInt32(0 if math.isnan(left) else left),
framework.Convert.ToInt32(0 if math.isnan(top) else top),
framework.Convert.ToInt32(0 if math.isnan(width) else width),
framework.Convert.ToInt32(0 if math.isnan(height) else height)
)
for scr in framework.Forms.Screen.AllScreens:
if bounds.IntersectsWith(scr.Bounds):
return True
return False
``` | ### `fuzzy_search_ratio(target_string, sfilter, regex=False)` Match target string against the filter and return a match ratio. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `target_string` | `str` | target string | _required_ | | `sfilter` | `str` | search term | _required_ | | `regex` | `bool` | treat the sfilter as regular expression pattern | `False` | Returns: | Type | Description | | --- | --- | | `int` | integer between 0 to 100, with 100 being the exact match | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
``` | ```md-code__content
def fuzzy_search_ratio(target_string, sfilter, regex=False):
"""Match target string against the filter and return a match ratio.
Args:
target_string (str): target string
sfilter (str): search term
regex (bool): treat the sfilter as regular expression pattern
Returns:
(int): integer between 0 to 100, with 100 being the exact match
"""
tstring = target_string
# process regex here. It's a yes no situation (100 or 0)
if regex:
try:
if re.search(sfilter, tstring):
return 100
except Exception:
pass
return 0
# 100 for identical matches
if sfilter == tstring:
return 100
# 98 to 99 reserved (2 scores)
# 97 for identical non-case-sensitive matches
lower_tstring = tstring.lower()
lower_sfilter_str = sfilter.lower()
if lower_sfilter_str == lower_tstring:
return 97
# 95 to 96 reserved (2 scores)
# 93 to 94 for inclusion matches
if sfilter in tstring:
return 94
if lower_sfilter_str in lower_tstring:
return 93
# 91 to 92 reserved (2 scores)
## 80 to 90 for parts matches
tstring_parts = tstring.split()
sfilter_parts = sfilter.split()
if all(x in tstring_parts for x in sfilter_parts):
return 90
# 88 to 89 reserved (2 scores)
lower_tstring_parts = [x.lower() for x in tstring_parts]
lower_sfilter_parts = [x.lower() for x in sfilter_parts]
# exclude override
if any(x[0] == '!' for x in sfilter_parts):
exclude_indices = [
lower_sfilter_parts.index(i) for i in lower_sfilter_parts
if i[0] == '!'
]
exclude_indices.reverse()
exclude_list = [
lower_sfilter_parts.pop(i) for i in exclude_indices
]
for e in exclude_list:
# doesn't contain
if len(e) > 1:
exclude_string = e[1:]
if any(
[exclude_string in
part for part in lower_tstring_parts]
):
return 0
if all(x in lower_tstring_parts for x in lower_sfilter_parts):
return 87
# 85 to 86 reserved (2 scores)
if all(x in tstring for x in sfilter_parts):
return 84
# 82 to 83 reserved (2 scores)
if all(x in lower_tstring for x in lower_sfilter_parts):
return 81
# 80 reserved
return 0
``` | ### `get_exe_version(exepath)` Extract Product Version value from EXE file. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1334
1335
1336
1337
``` | ```md-code__content
def get_exe_version(exepath):
"""Extract Product Version value from EXE file."""
version_info = framework.Diagnostics.FileVersionInfo.GetVersionInfo(exepath)
return version_info.ProductVersion
``` | ### `get_reg_key(key, subkey)` Get value of the given Windows registry key and subkey. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `key` | `PyHKEY` | parent registry key | _required_ | | `subkey` | `str` | subkey path | _required_ | Returns: | Type | Description | | --- | --- | | `PyHKEY` | registry key if found, None if not found | Examples: ```md-code__content get_reg_key(wr.HKEY_CURRENT_USER, 'Control Panel/International') ``` Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
``` | ````md-code__content
def get_reg_key(key, subkey):
"""Get value of the given Windows registry key and subkey.
Args:
key (PyHKEY): parent registry key
subkey (str): subkey path
Returns:
(PyHKEY): registry key if found, None if not found
Examples:
```python
get_reg_key(wr.HKEY_CURRENT_USER, 'Control Panel/International')
```

"""
try:
return wr.OpenKey(key, subkey, 0, wr.KEY_READ)
except Exception:
return None
```` | ### `kill_tasks(task_name)` Kill running tasks matching task\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `task_name` | `str` | task name | _required_ | Examples: ```md-code__content kill_tasks('Revit.exe') ``` Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
``` | ````md-code__content
def kill_tasks(task_name):
"""Kill running tasks matching task_name.
Args:
task_name (str): task name
Examples:
```python
kill_tasks('Revit.exe')
```
"""
os.system("taskkill /f /im %s" % task_name)
```` | ### `int2hex_long(number)` Integer to hexadecimal string. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1376
1377
1378
1379
``` | ```md-code__content
def int2hex_long(number):
"""Integer to hexadecimal string."""
# python 2 fix of addin 'L' to long integers
return hex(number).replace('L', '')
``` | ### `hex2int_long(hex_string)` Hexadecimal string to Integer. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1382
1383
1384
1385
1386
``` | ```md-code__content
def hex2int_long(hex_string):
"""Hexadecimal string to Integer."""
# python 2 fix of addin 'L' to long integers
hex_string.replace('L', '')
return int(hex_string, 16)
``` | ### `split_words(input_string)` Splits given string by uppercase characters. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input_string` | `str` | input string | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | split string | Examples: ```md-code__content split_words("UIApplication_ApplicationClosing") ``` \['UIApplication', 'Application', 'Closing'\] Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
``` | ````md-code__content
def split_words(input_string):
"""Splits given string by uppercase characters.
Args:
input_string (str): input string
Returns:
(list[str]): split string
Examples:
```python
split_words("UIApplication_ApplicationClosing")
```
['UIApplication', 'Application', 'Closing']
"""
parts = []
part = ""
for c in input_string:
if c.isalpha():
if c.isupper() and part and part[-1].islower():
if part:
parts.append(part.strip())
part = c
else:
part += c
parts.append(part)
return parts
```` | ### `get_paper_sizes(printer_name=None)` Get paper sizes defined on this system. Returns: | Type | Description | | --- | --- | | `list[]` | list of papersize instances | Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
``` | ```md-code__content
def get_paper_sizes(printer_name=None):
"""Get paper sizes defined on this system.
Returns:
(list[]): list of papersize instances
"""
print_settings = framework.Drawing.Printing.PrinterSettings()
if printer_name:
print_settings.PrinterName = printer_name
return list(print_settings.PaperSizes)
``` | ### `get_integer_length(number)` Return digit length of given number. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1430
1431
1432
``` | ```md-code__content
def get_integer_length(number):
"""Return digit length of given number."""
return 1 if number == 0 else (math.floor(math.log10(number)) + 1)
``` | ### `get_my_ip()` Return local ip address of this machine. Source code in `pyrevitlib/pyrevit/coreutils/__init__.py` | | | | --- | --- | | ```
1435
1436
1437
``` | ```md-code__content
def get_my_ip():
"""Return local ip address of this machine."""
return socket.gethostbyname(socket.gethostname())
``` | Back to top ## pyRevit Labs Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/labs/#pyrevit.labs) # labs Wrapper module for pyRevitLabs functionality. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `config = NLog.Config.LoggingConfiguration()``module-attribute` ### `target = PyRevitOutputTarget()``module-attribute` ### `nlog_mlogger = NLog.LogManager.GetLogger(__name__)``module-attribute` ## Classes ### `PyRevitOutputTarget` Bases: `TargetWithLayout` NLog target to direct log messages to pyRevit output window. #### Functions ##### `Write(asyncLogEvent)` Write event handler. Source code in `pyrevitlib/pyrevit/labs.py` | | | | --- | --- | | ```
67
68
69
70
71
72
73
74
75
``` | ```md-code__content
def Write(self, asyncLogEvent):
"""Write event handler."""
try:
event = asyncLogEvent.LogEvent
level = self.convert_level(event.Level)
if mlogger.is_enabled_for(level):
print(self.Layout.Render(event)) #pylint: disable=E1101
except Exception as e:
print(e)
``` | ##### `convert_level(nlog_level)` Convert Nlog levels to pything logging levels. Source code in `pyrevitlib/pyrevit/labs.py` | | | | --- | --- | | ```
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
``` | ```md-code__content
def convert_level(self, nlog_level):
"""Convert Nlog levels to pything logging levels."""
if nlog_level == NLog.LogLevel.Fatal:
return logging.CRITICAL
elif nlog_level == NLog.LogLevel.Error:
return logging.ERROR
elif nlog_level == NLog.LogLevel.Info:
return logging.INFO
elif nlog_level == NLog.LogLevel.Debug:
return logging.DEBUG
elif nlog_level == NLog.LogLevel.Off:
return logging.DEBUG
elif nlog_level == NLog.LogLevel.Trace:
return logging.DEBUG
elif nlog_level == NLog.LogLevel.Warn:
return logging.WARNING
``` | ## Functions ### `extract_build_from_exe(proc_path)` Extract build number from host .exe file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `proc_path` | `str` | full path of the host .exe file | _required_ | Returns: | Type | Description | | --- | --- | | `str` | build number (e.g. '20170927\_1515(x64)') | Source code in `pyrevitlib/pyrevit/labs.py` | | | | --- | --- | | ```
95
96
97
98
99
100
101
102
103
104
105
106
107
108
``` | ```md-code__content
def extract_build_from_exe(proc_path):
"""Extract build number from host .exe file.
Args:
proc_path (str): full path of the host .exe file
Returns:
(str): build number (e.g. '20170927_1515(x64)')
"""
# Revit 2021 has a bug on .VersionBuild
## it reports identical value as .VersionNumber
pinfo = TargetApps.Revit.RevitProductData.GetBinaryProductInfo(proc_path)
return "{}({})".format(pinfo.build, pinfo.target) \
if pinfo.build else "20000101_0000(x64)"
``` | Back to top ## pyRevit Forms Reference [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/forms/#pyrevit.forms) # forms Reusable WPF forms for pyRevit. Examples: ```md-code__content from pyrevit.forms import WPFWindow ``` ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `DEFAULT_CMDSWITCHWND_WIDTH = 600``module-attribute` ### `DEFAULT_SEARCHWND_WIDTH = 600``module-attribute` ### `DEFAULT_SEARCHWND_HEIGHT = 100``module-attribute` ### `DEFAULT_INPUTWINDOW_WIDTH = 500``module-attribute` ### `DEFAULT_INPUTWINDOW_HEIGHT = 600``module-attribute` ### `DEFAULT_RECOGNIZE_ACCESS_KEY = False``module-attribute` ### `WPF_HIDDEN = framework.Windows.Visibility.Hidden``module-attribute` ### `WPF_COLLAPSED = framework.Windows.Visibility.Collapsed``module-attribute` ### `WPF_VISIBLE = framework.Windows.Visibility.Visible``module-attribute` ### `XAML_FILES_DIR = op.dirname(__file__)``module-attribute` ### `ParamDef = namedtuple('ParamDef', ['name', 'istype', 'definition', 'isreadonly'])``module-attribute` Parameter definition tuple. Attributes: | Name | Type | Description | | --- | --- | --- | | `name` | `str` | parameter name | | `istype` | `bool` | true if type parameter, otherwise false | | `definition` | `Definition` | parameter definition object | | `isreadonly` | `bool` | true if the parameter value can't be edited | ## Classes ### `reactive(getter)` Bases: `property` Decorator for WPF bound properties. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
87
88
89
90
91
92
93
``` | ```md-code__content
def __init__(self, getter):
def newgetter(ui_control):
try:
return getter(ui_control)
except AttributeError:
return None
super(reactive, self).__init__(newgetter)
``` | #### Functions ##### `setter(setter)` Property setter. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
95
96
97
98
99
100
101
102
103
104
105
106
``` | ```md-code__content
def setter(self, setter):
"""Property setter."""
def newsetter(ui_control, newvalue):
oldvalue = self.fget(ui_control)
if oldvalue != newvalue:
setter(ui_control, newvalue)
ui_control.OnPropertyChanged(setter.__name__)
return property(
fget=self.fget,
fset=newsetter,
fdel=self.fdel,
doc=self.__doc__)
``` | ### `Reactive` Bases: `INotifyPropertyChanged` WPF property updator base mixin. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ### `WindowToggler(window)` Bases: `object` Context manager to toggle window visibility. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
134
135
``` | ```md-code__content
def __init__(self, window):
self._window = window
``` | ### `WPFWindow(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Bases: `Window` WPF Window base class for all pyRevit forms. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml source filepath or xaml content | _required_ | | `literal_string` | `bool` | xaml\_source contains xaml content, not filepath | `False` | | `handle_esc` | `bool` | handle Escape button and close the window | `True` | | `set_owner` | `bool` | set the owner of window to host app window | `True` | Examples: ```md-code__content from pyrevit import forms layout = '' \ '' w = forms.WPFWindow(layout, literal_string=True) w.show() ``` Initialize WPF window and resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
168
169
170
171
172
173
174
175
176
``` | ```md-code__content
def __init__(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Initialize WPF window and resources."""
# load xaml
self.load_xaml(
xaml_source,
literal_string=literal_string,
handle_esc=handle_esc,
set_owner=set_owner
)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(modal=False)` Show window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
323
324
325
326
327
328
``` | ```md-code__content
def show(self, modal=False):
"""Show window."""
if modal:
return self.ShowDialog()
# else open non-modal
self.Show()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ### `WPFPanel()` Bases: `Page` WPF panel base class for all pyRevit dockable panels. panel\_id (str) must be set on the type to dockable panel uuid panel\_source (str): xaml source filepath Examples: ```md-code__content from pyrevit import forms class MyPanel(forms.WPFPanel): panel_id = "181e05a4-28f6-4311-8a9f-d2aa528c8755" panel_source = "MyPanel.xaml" forms.register_dockable_panel(MyPanel) # then from the button that needs to open the panel forms.open_dockable_panel("181e05a4-28f6-4311-8a9f-d2aa528c8755") ``` Initialize WPF panel and resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
``` | ```md-code__content
def __init__(self):
"""Initialize WPF panel and resources."""
if not self.panel_id:
raise PyRevitException("\"panel_id\" property is not set")
if not self.panel_source:
raise PyRevitException("\"panel_source\" property is not set")
if not op.exists(self.panel_source):
wpf.LoadComponent(self,
os.path.join(EXEC_PARAMS.command_path,
self.panel_source))
else:
wpf.LoadComponent(self, self.panel_source)
# set properties
self.thread_id = framework.get_current_thread_id()
WPFWindow.setup_resources(self)
``` | #### Attributes ##### `panel_id = None``class-attribute``instance-attribute` ##### `panel_source = None``class-attribute``instance-attribute` ##### `thread_id = framework.get_current_thread_id()``instance-attribute` #### Functions ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
493
494
495
496
497
498
499
500
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
502
503
504
505
506
507
508
509
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
WPFPanel.hide_element(*wpf_elements)
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
511
512
513
514
515
516
517
518
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
WPFPanel.show_element(*wpf_elements)
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
520
521
522
523
524
525
526
527
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
WPFPanel.toggle_element(*wpf_elements)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
529
530
531
532
533
534
535
536
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
WPFPanel.disable_element(*wpf_elements)
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
538
539
540
541
542
543
544
545
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list): WPF framework elements to be enabled
"""
WPFPanel.enable_element(*wpf_elements)
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
547
548
549
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ### `TemplateUserInputWindow(context, title, width, height, **kwargs)` Bases: `WPFWindow` Base class for pyRevit user input standard forms. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `any` | window context element(s) | _required_ | | `title` | `str` | window title | _required_ | | `width` | `int` | window width | _required_ | | `height` | `int` | window height | _required_ | | `**kwargs` | `Any` | other arguments to be passed to :func: `_setup` | `{}` | Initialize user input window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
``` | ```md-code__content
def __init__(self, context, title, width, height, **kwargs):
"""Initialize user input window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source),
handle_esc=True)
self.Title = title or 'pyRevit'
self.Width = width
self.Height = height
self._context = context
self.response = None
# parent window?
owner = kwargs.get('owner', None)
if owner:
# set wpf windows directly
self.Owner = owner
self.WindowStartupLocation = \
framework.Windows.WindowStartupLocation.CenterOwner
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `xaml_source = 'BaseWindow.xaml'``class-attribute``instance-attribute` ##### `Title = title or 'pyRevit'``instance-attribute` ##### `Width = width``instance-attribute` ##### `Height = height``instance-attribute` ##### `response = None``instance-attribute` ##### `Owner = owner``instance-attribute` ##### `WindowStartupLocation = framework.Windows.WindowStartupLocation.CenterOwner``instance-attribute` #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `show(context, title='User Input', width=DEFAULT_INPUTWINDOW_WIDTH, height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs)``classmethod` Show user input window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `any` | window context element(s) | _required_ | | `title` | `str` | window title | `'User Input'` | | `width` | `int` | window width | `DEFAULT_INPUTWINDOW_WIDTH` | | `height` | `int` | window height | `DEFAULT_INPUTWINDOW_HEIGHT` | | `**kwargs` | `any` | other arguments to be passed to window | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
``` | ```md-code__content
@classmethod
def show(cls, context, #pylint: disable=W0221
title='User Input',
width=DEFAULT_INPUTWINDOW_WIDTH,
height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs):
"""Show user input window.
Args:
context (any): window context element(s)
title (str): window title
width (int): window width
height (int): window height
**kwargs (any): other arguments to be passed to window
"""
dlg = cls(context, title, width, height, **kwargs)
dlg.ShowDialog()
return dlg.response
``` | ### `TemplateListItem(orig_item, checked=False, checkable=True, name_attr=None)` Bases: `Reactive` Base class for checkbox option wrapping another object. Initialize the checkbox option and wrap given obj. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `orig_item` | `any` | Object to wrap (must have name property
or be convertable to string with str() | _required_ | | `checked` | `bool` | Initial state. Defaults to False | `False` | | `checkable` | `bool` | Use checkbox for items | `True` | | `name_attr` | `str` | Get this attribute of wrapped object as name | `None` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
``` | ```md-code__content
def __init__(self, orig_item,
checked=False, checkable=True, name_attr=None):
"""Initialize the checkbox option and wrap given obj.
Args:
orig_item (any): Object to wrap (must have name property
or be convertable to string with str()
checked (bool): Initial state. Defaults to False
checkable (bool): Use checkbox for items
name_attr (str): Get this attribute of wrapped object as name
"""
super(TemplateListItem, self).__init__()
self.item = orig_item
self.state = checked
self._nameattr = name_attr
self._checkable = checkable
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `name``property` Name property. ##### `checkable``property``writable` List Item CheckBox Visibility. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ### `SelectFromList(context, title, width, height, **kwargs)` Bases: `TemplateUserInputWindow` Standard form to select from a list of items. Any object can be passed in a list to the `context` argument. This class wraps the objects passed to context, in `TemplateListItem`. This class provides the necessary mechanism to make this form work both for selecting items from a list, and from a list of checkboxes. See the list of arguments below for additional options and features. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `list[str] or dict[list[str]]` | list of items to be selected from
OR
dict of list of items to be selected from.
use dict when input items need to be grouped
e.g. List of sheets grouped by sheet set. | _required_ | | `title` | `str` | window title. see super class for defaults. | _required_ | | `width` | `int` | window width. see super class for defaults. | _required_ | | `height` | `int` | window height. see super class for defaults. | _required_ | Other Parameters: | Name | Type | Description | | --- | --- | --- | | `button_name` | `str` | name of select button. defaults to 'Select' | | `name_attr` | `str` | object attribute that should be read as item name. | | `multiselect` | `bool` | allow multi-selection (uses check boxes). defaults to False | | `info_panel` | `bool` | show information panel and fill with .description property of item | | `return_all` | `bool` | return all items. This is handly when some input items have states
and the script needs to check the state changes on all items.
This options works in multiselect mode only. defaults to False | | `filterfunc` | `function` | filter function to be applied to context items. | | `resetfunc` | `function` | reset function to be called when user clicks on Reset button | | `group_selector_title` | `str` | title for list group selector. defaults to 'List Group' | | `default_group` | `str` | name of defautl group to be selected | | `sort_groups` | `str` | Determines the sorting type applied to the list groups. This attribute can take one of the following values:
'sorted': This will sort the groups in standard alphabetical order
'natural': This will sort the groups in a manner that is more intuitive for human perception, especially when there are numbers involved.
'unsorted': The groups will maintain the original order in which they were provided, without any reordering.
Defaults to 'sorted'. | Examples: ```md-code__content from pyrevit import forms items = ['item1', 'item2', 'item3'] forms.SelectFromList.show(items, button_name='Select Item') ['item1'] ``` ```md-code__content from pyrevit import forms ops = [viewsheet1, viewsheet2, viewsheet3] res = forms.SelectFromList.show(ops, multiselect=False, name_attr='Name', button_name='Select Sheet') ``` ```md-code__content from pyrevit import forms ops = {'Sheet Set A': [viewsheet1, viewsheet2, viewsheet3], 'Sheet Set B': [viewsheet4, viewsheet5, viewsheet6]} res = forms.SelectFromList.show(ops, multiselect=True, name_attr='Name', group_selector_title='Sheet Sets', button_name='Select Sheets', sort_groups='sorted') ``` This module also provides a wrapper base class :obj: `TemplateListItem` for when the checkbox option is wrapping another element, e.g. a Revit ViewSheet. Derive from this base class and define the name property to customize how the checkbox is named on the dialog. ```md-code__content from pyrevit import forms class MyOption(forms.TemplateListItem): @property def name(self): return '{} - {}{}'.format(self.item.SheetNumber, self.item.SheetNumber) ops = [MyOption('op1'), MyOption('op2', True), MyOption('op3')] res = forms.SelectFromList.show(ops, multiselect=True, button_name='Select Item') [bool(x) for x in res] # or [x.state for x in res] [True, False, True] ``` Initialize user input window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
``` | ```md-code__content
def __init__(self, context, title, width, height, **kwargs):
"""Initialize user input window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source),
handle_esc=True)
self.Title = title or 'pyRevit'
self.Width = width
self.Height = height
self._context = context
self.response = None
# parent window?
owner = kwargs.get('owner', None)
if owner:
# set wpf windows directly
self.Owner = owner
self.WindowStartupLocation = \
framework.Windows.WindowStartupLocation.CenterOwner
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `Title = title or 'pyRevit'``instance-attribute` ##### `Width = width``instance-attribute` ##### `Height = height``instance-attribute` ##### `response = None``instance-attribute` ##### `Owner = owner``instance-attribute` ##### `WindowStartupLocation = framework.Windows.WindowStartupLocation.CenterOwner``instance-attribute` ##### `in_check = False``class-attribute``instance-attribute` ##### `in_uncheck = False``class-attribute``instance-attribute` ##### `xaml_source = 'SelectFromList.xaml'``class-attribute``instance-attribute` ##### `use_regex``property` Is using regex? #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(context, title='User Input', width=DEFAULT_INPUTWINDOW_WIDTH, height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs)``classmethod` Show user input window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `any` | window context element(s) | _required_ | | `title` | `str` | window title | `'User Input'` | | `width` | `int` | window width | `DEFAULT_INPUTWINDOW_WIDTH` | | `height` | `int` | window height | `DEFAULT_INPUTWINDOW_HEIGHT` | | `**kwargs` | `any` | other arguments to be passed to window | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
``` | ```md-code__content
@classmethod
def show(cls, context, #pylint: disable=W0221
title='User Input',
width=DEFAULT_INPUTWINDOW_WIDTH,
height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs):
"""Show user input window.
Args:
context (any): window context element(s)
title (str): window title
width (int): window width
height (int): window height
**kwargs (any): other arguments to be passed to window
"""
dlg = cls(context, title, width, height, **kwargs)
dlg.ShowDialog()
return dlg.response
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `toggle_all(sender, args)` Handle toggle all button to toggle state of all check boxes. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1091
1092
1093
``` | ```md-code__content
def toggle_all(self, sender, args): #pylint: disable=W0613
"""Handle toggle all button to toggle state of all check boxes."""
self._set_states(flip=True)
``` | ##### `check_all(sender, args)` Handle check all button to mark all check boxes as checked. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1095
1096
1097
``` | ```md-code__content
def check_all(self, sender, args): #pylint: disable=W0613
"""Handle check all button to mark all check boxes as checked."""
self._set_states(state=True)
``` | ##### `uncheck_all(sender, args)` Handle uncheck all button to mark all check boxes as un-checked. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1099
1100
1101
``` | ```md-code__content
def uncheck_all(self, sender, args): #pylint: disable=W0613
"""Handle uncheck all button to mark all check boxes as un-checked."""
self._set_states(state=False)
``` | ##### `check_selected(sender, args)` Mark selected checkboxes as checked. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1103
1104
1105
1106
1107
1108
1109
1110
``` | ```md-code__content
def check_selected(self, sender, args): #pylint: disable=W0613
"""Mark selected checkboxes as checked."""
if not self.in_check:
try:
self.in_check = True
self._set_states(state=True, selected=True)
finally:
self.in_check = False
``` | ##### `uncheck_selected(sender, args)` Mark selected checkboxes as unchecked. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1112
1113
1114
1115
1116
1117
1118
1119
``` | ```md-code__content
def uncheck_selected(self, sender, args): #pylint: disable=W0613
"""Mark selected checkboxes as unchecked."""
if not self.in_uncheck:
try:
self.in_uncheck = True
self._set_states(state=False, selected=True)
finally:
self.in_uncheck = False
``` | ##### `button_reset(sender, args)` Handle reset button click. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1121
1122
1123
1124
1125
``` | ```md-code__content
def button_reset(self, sender, args):#pylint: disable=W0613
"""Handle reset button click."""
if self.reset_func:
all_items = self.list_lb.ItemsSource
self.reset_func(all_items)
``` | ##### `button_select(sender, args)` Handle select button click. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1127
1128
1129
1130
``` | ```md-code__content
def button_select(self, sender, args): #pylint: disable=W0613
"""Handle select button click."""
self.response = self._get_options()
self.Close()
``` | ##### `search_txt_changed(sender, args)` Handle text change in search box. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
``` | ```md-code__content
def search_txt_changed(self, sender, args): #pylint: disable=W0613
"""Handle text change in search box."""
if self.info_panel:
self._toggle_info_panel(state=False)
if self.search_tb.Text == '':
self.hide_element(self.clrsearch_b)
else:
self.show_element(self.clrsearch_b)
self._list_options(option_filter=self.search_tb.Text)
``` | ##### `selection_changed(sender, args)` Handle selection change. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1144
1145
1146
1147
1148
1149
``` | ```md-code__content
def selection_changed(self, sender, args):
"""Handle selection change."""
if self.info_panel:
self._toggle_info_panel(state=False)
self._list_options(option_filter=self.search_tb.Text)
``` | ##### `selected_item_changed(sender, args)` Handle selected item change. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1151
1152
1153
1154
1155
1156
``` | ```md-code__content
def selected_item_changed(self, sender, args):
"""Handle selected item change."""
if self.info_panel and self.list_lb.SelectedItem is not None:
self._toggle_info_panel(state=True)
self.infoData.Text = \
getattr(self.list_lb.SelectedItem, 'description', '')
``` | ##### `toggle_regex(sender, args)` Activate regex in search. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1158
1159
1160
1161
1162
1163
1164
``` | ```md-code__content
def toggle_regex(self, sender, args):
"""Activate regex in search."""
self.regexToggle_b.Content = \
self.Resources['regexIcon'] if self.use_regex \
else self.Resources['filterIcon']
self.search_txt_changed(sender, args)
self.search_tb.Focus()
``` | ##### `clear_search(sender, args)` Clear search box. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1166
1167
1168
1169
1170
``` | ```md-code__content
def clear_search(self, sender, args): #pylint: disable=W0613
"""Clear search box."""
self.search_tb.Text = ' '
self.search_tb.Clear()
self.search_tb.Focus()
``` | ### `CommandSwitchWindow(context, title, width, height, **kwargs)` Bases: `TemplateUserInputWindow` Standard form to select from a list of command options. Other Parameters: | Name | Type | Description | | --- | --- | --- | | `context` | `list[str]` | list of command options to choose from | | `switches` | `list[str]` | list of on/off switches | | `message` | `str` | window title message | | `config` | `dict` | dictionary of config dicts for options or switches | | `recognize_access_key` | `bool` | recognize '\_' as mark of access key | Returns: | Type | Description | | --- | --- | | `str | tuple[str, dict]` | name of selected option.
if `switches` option is used, returns a tuple
of selection option name and dict of switches | Examples: This is an example with series of command options: ```md-code__content from pyrevit import forms ops = ['option1', 'option2', 'option3', 'option4'] forms.CommandSwitchWindow.show(ops, message='Select Option') 'option2' ``` A more advanced example of combining command options, on/off switches, and option or switch configuration options: ```md-code__content from pyrevit import forms ops = ['option1', 'option2', 'option3', 'option4'] switches = ['switch1', 'switch2'] cfgs = {'option1': { 'background': '0xFF55FF'}} rops, rswitches = forms.CommandSwitchWindow.show( ops, switches=switches message='Select Option', config=cfgs, recognize_access_key=False ) rops 'option2' rswitches {'switch1': False, 'switch2': True} ``` Initialize user input window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
``` | ```md-code__content
def __init__(self, context, title, width, height, **kwargs):
"""Initialize user input window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source),
handle_esc=True)
self.Title = title or 'pyRevit'
self.Width = width
self.Height = height
self._context = context
self.response = None
# parent window?
owner = kwargs.get('owner', None)
if owner:
# set wpf windows directly
self.Owner = owner
self.WindowStartupLocation = \
framework.Windows.WindowStartupLocation.CenterOwner
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `Title = title or 'pyRevit'``instance-attribute` ##### `Width = width``instance-attribute` ##### `Height = height``instance-attribute` ##### `response = None``instance-attribute` ##### `Owner = owner``instance-attribute` ##### `WindowStartupLocation = framework.Windows.WindowStartupLocation.CenterOwner``instance-attribute` ##### `xaml_source = 'CommandSwitchWindow.xaml'``class-attribute``instance-attribute` #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(context, title='User Input', width=DEFAULT_INPUTWINDOW_WIDTH, height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs)``classmethod` Show user input window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `any` | window context element(s) | _required_ | | `title` | `str` | window title | `'User Input'` | | `width` | `int` | window width | `DEFAULT_INPUTWINDOW_WIDTH` | | `height` | `int` | window height | `DEFAULT_INPUTWINDOW_HEIGHT` | | `**kwargs` | `any` | other arguments to be passed to window | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
``` | ```md-code__content
@classmethod
def show(cls, context, #pylint: disable=W0221
title='User Input',
width=DEFAULT_INPUTWINDOW_WIDTH,
height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs):
"""Show user input window.
Args:
context (any): window context element(s)
title (str): window title
width (int): window width
height (int): window height
**kwargs (any): other arguments to be passed to window
"""
dlg = cls(context, title, width, height, **kwargs)
dlg.ShowDialog()
return dlg.response
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `handle_click(sender, args)` Handle mouse click. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1304
1305
1306
``` | ```md-code__content
def handle_click(self, sender, args): #pylint: disable=W0613
"""Handle mouse click."""
self.Close()
``` | ##### `handle_input_key(sender, args)` Handle keyboard inputs. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
``` | ```md-code__content
def handle_input_key(self, sender, args):
"""Handle keyboard inputs."""
if args.Key == Input.Key.Escape:
if self.search_tb.Text:
self.search_tb.Text = ''
else:
self.Close()
elif args.Key == Input.Key.Enter:
active_button = self._get_active_button()
if active_button:
if isinstance(active_button,
framework.Controls.Primitives.ToggleButton):
return
self.process_option(active_button, None)
args.Handled = True
elif args.Key != Input.Key.Tab \
and args.Key != Input.Key.Space\
and args.Key != Input.Key.LeftShift\
and args.Key != Input.Key.RightShift:
self.search_tb.Focus()
``` | ##### `search_txt_changed(sender, args)` Handle text change in search box. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1329
1330
1331
``` | ```md-code__content
def search_txt_changed(self, sender, args): #pylint: disable=W0613
"""Handle text change in search box."""
self._filter_options(option_filter=self.search_tb.Text)
``` | ##### `process_option(sender, args)` Handle click on command option button. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1333
1334
1335
1336
1337
``` | ```md-code__content
def process_option(self, sender, args): #pylint: disable=W0613
"""Handle click on command option button."""
self.Close()
if sender:
self._setup_response(response=sender.Content)
``` | ### `GetValueWindow(context, title, width, height, **kwargs)` Bases: `TemplateUserInputWindow` Standard form to get simple values from user. Examples: ```md-code__content from pyrevit import forms items = ['item1', 'item2', 'item3'] forms.SelectFromList.show(items, button_name='Select Item') ['item1'] ``` Initialize user input window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
``` | ```md-code__content
def __init__(self, context, title, width, height, **kwargs):
"""Initialize user input window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source),
handle_esc=True)
self.Title = title or 'pyRevit'
self.Width = width
self.Height = height
self._context = context
self.response = None
# parent window?
owner = kwargs.get('owner', None)
if owner:
# set wpf windows directly
self.Owner = owner
self.WindowStartupLocation = \
framework.Windows.WindowStartupLocation.CenterOwner
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `Title = title or 'pyRevit'``instance-attribute` ##### `Width = width``instance-attribute` ##### `Height = height``instance-attribute` ##### `response = None``instance-attribute` ##### `Owner = owner``instance-attribute` ##### `WindowStartupLocation = framework.Windows.WindowStartupLocation.CenterOwner``instance-attribute` ##### `xaml_source = 'GetValueWindow.xaml'``class-attribute``instance-attribute` #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(context, title='User Input', width=DEFAULT_INPUTWINDOW_WIDTH, height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs)``classmethod` Show user input window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `context` | `any` | window context element(s) | _required_ | | `title` | `str` | window title | `'User Input'` | | `width` | `int` | window width | `DEFAULT_INPUTWINDOW_WIDTH` | | `height` | `int` | window height | `DEFAULT_INPUTWINDOW_HEIGHT` | | `**kwargs` | `any` | other arguments to be passed to window | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
``` | ```md-code__content
@classmethod
def show(cls, context, #pylint: disable=W0221
title='User Input',
width=DEFAULT_INPUTWINDOW_WIDTH,
height=DEFAULT_INPUTWINDOW_HEIGHT, **kwargs):
"""Show user input window.
Args:
context (any): window context element(s)
title (str): window title
width (int): window width
height (int): window height
**kwargs (any): other arguments to be passed to window
"""
dlg = cls(context, title, width, height, **kwargs)
dlg.ShowDialog()
return dlg.response
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `string_value_changed(sender, args)` Handle string vlaue update event. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
``` | ```md-code__content
def string_value_changed(self, sender, args): #pylint: disable=unused-argument
"""Handle string vlaue update event."""
filtered_rvalues = \
sorted([x for x in self.reserved_values
if self.stringValue_tb.Text == str(x)])
similar_rvalues = \
sorted([x for x in self.reserved_values
if self.stringValue_tb.Text in str(x)],
reverse=True)
filtered_rvalues.extend(similar_rvalues)
if filtered_rvalues:
self.reservedValuesList.ItemsSource = filtered_rvalues
self.show_element(self.reservedValuesListPanel)
self.okayButton.IsEnabled = \
self.stringValue_tb.Text not in filtered_rvalues
else:
self.reservedValuesList.ItemsSource = []
self.hide_element(self.reservedValuesListPanel)
self.okayButton.IsEnabled = True
``` | ##### `select(sender, args)` Process input data and set the response. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
``` | ```md-code__content
def select(self, sender, args): #pylint: disable=W0613
"""Process input data and set the response."""
self.Close()
if self.value_type == 'string':
self.response = self.stringValue_tb.Text
elif self.value_type == 'dropdown':
self.response = self.dropdown_cb.SelectedItem
elif self.value_type == 'date':
if self.datePicker.SelectedDate:
datestr = self.datePicker.SelectedDate.ToString("MM/dd/yyyy")
self.response = datetime.datetime.strptime(datestr, r'%m/%d/%Y')
else:
self.response = None
elif self.value_type == 'slider':
self.response = self.numberPicker.Value
``` | ### `TemplatePromptBar(height=32, **kwargs)` Bases: `WPFWindow` Template context-manager class for creating prompt bars. Prompt bars are show at the top of the active Revit window and are designed for better prompt visibility. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `height` | `int` | window height | `32` | | `**kwargs` | `Any` | other arguments to be passed to :func: `_setup` | `{}` | Initialize user prompt window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1443
1444
1445
1446
1447
1448
1449
1450
``` | ```md-code__content
def __init__(self, height=32, **kwargs):
"""Initialize user prompt window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source))
self.user_height = height
self.update_window()
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `xaml_source = 'TemplatePromptBar.xaml'``class-attribute``instance-attribute` ##### `user_height = height``instance-attribute` #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(modal=False)` Show window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
323
324
325
326
327
328
``` | ```md-code__content
def show(self, modal=False):
"""Show window."""
if modal:
return self.ShowDialog()
# else open non-modal
self.Show()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `update_window()` Update the prompt bar to match Revit window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
``` | ```md-code__content
def update_window(self):
"""Update the prompt bar to match Revit window."""
screen_area = HOST_APP.proc_screen_workarea
scale_factor = 1.0 / HOST_APP.proc_screen_scalefactor
top = left = width = height = 0
window_rect = revit.ui.get_window_rectangle()
# set width and height
width = window_rect.Right - window_rect.Left
height = self.user_height
top = window_rect.Top
# in maximized window, the top might be off the active screen
# due to windows thicker window frames
# lets cut the height and re-adjust the top
top_diff = abs(screen_area.Top - top)
if 10 > top_diff > 0 and top_diff < height:
height -= top_diff
top = screen_area.Top
left = window_rect.Left
# in maximized window, Left also might be off the active screen
# due to windows thicker window frames
# let's fix the width to accomodate the extra pixels as well
left_diff = abs(screen_area.Left - left)
if 10 > left_diff > 0 and left_diff < width:
# deduct two times the left negative offset since this extra
# offset happens on both left and right side
width -= left_diff * 2
left = screen_area.Left
self.Top = top * scale_factor
self.Left = left * scale_factor
self.Width = width * scale_factor
self.Height = height
``` | ### `WarningBar(height=32, **kwargs)` Bases: `TemplatePromptBar` Show warning bar at the top of Revit window. Other Parameters: | Name | Type | Description | | --- | --- | --- | | `title` | `string` | warning bar text | Examples: ```md-code__content with WarningBar(title='my warning'): # do stuff ``` Initialize user prompt window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1443
1444
1445
1446
1447
1448
1449
1450
``` | ```md-code__content
def __init__(self, height=32, **kwargs):
"""Initialize user prompt window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source))
self.user_height = height
self.update_window()
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `user_height = height``instance-attribute` ##### `xaml_source = 'WarningBar.xaml'``class-attribute``instance-attribute` #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(modal=False)` Show window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
323
324
325
326
327
328
``` | ```md-code__content
def show(self, modal=False):
"""Show window."""
if modal:
return self.ShowDialog()
# else open non-modal
self.Show()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `update_window()` Update the prompt bar to match Revit window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
``` | ```md-code__content
def update_window(self):
"""Update the prompt bar to match Revit window."""
screen_area = HOST_APP.proc_screen_workarea
scale_factor = 1.0 / HOST_APP.proc_screen_scalefactor
top = left = width = height = 0
window_rect = revit.ui.get_window_rectangle()
# set width and height
width = window_rect.Right - window_rect.Left
height = self.user_height
top = window_rect.Top
# in maximized window, the top might be off the active screen
# due to windows thicker window frames
# lets cut the height and re-adjust the top
top_diff = abs(screen_area.Top - top)
if 10 > top_diff > 0 and top_diff < height:
height -= top_diff
top = screen_area.Top
left = window_rect.Left
# in maximized window, Left also might be off the active screen
# due to windows thicker window frames
# let's fix the width to accomodate the extra pixels as well
left_diff = abs(screen_area.Left - left)
if 10 > left_diff > 0 and left_diff < width:
# deduct two times the left negative offset since this extra
# offset happens on both left and right side
width -= left_diff * 2
left = screen_area.Left
self.Top = top * scale_factor
self.Left = left * scale_factor
self.Width = width * scale_factor
self.Height = height
``` | ### `ProgressBar(height=32, **kwargs)` Bases: `TemplatePromptBar` Show progress bar at the top of Revit window. Other Parameters: | Name | Type | Description | | --- | --- | --- | | `title` | `string` | progress bar text, defaults to 0/100 progress format | | `indeterminate` | `bool` | create indeterminate progress bar | | `cancellable` | `bool` | add cancel button to progress bar | | `step` | `int` | update progress intervals | Examples: ```md-code__content from pyrevit import forms count = 1 with forms.ProgressBar(title='my command progress message') as pb: # do stuff pb.update_progress(count, 100) count += 1 ``` Progress bar title could also be customized to show the current and total progress values. In example below, the progress bar message will be in format "0 of 100" ```md-code__content with forms.ProgressBar(title='{value} of {max_value}') as pb: ``` By default progress bar updates the progress every time the .update\_progress method is called. For operations with a large number of max steps, the gui update process time will have a significate effect on the overall execution time of the command. In these cases, set the value of step argument to something larger than 1. In example below, the progress bar updates once per every 10 units of progress. ```md-code__content with forms.ProgressBar(title='message', steps=10): ``` Progress bar could also be set to indeterminate for operations of unknown length. In this case, the progress bar will show an infinitely running ribbon: ```md-code__content with forms.ProgressBar(title='message', indeterminate=True): ``` if cancellable is set on the object, a cancel button will show on the progress bar and .cancelled attribute will be set on the ProgressBar instance if users clicks on cancel button: ```md-code__content with forms.ProgressBar(title='message', cancellable=True) as pb: # do stuff if pb.cancelled: # wrap up and cancel operation ``` Initialize user prompt window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1443
1444
1445
1446
1447
1448
1449
1450
``` | ```md-code__content
def __init__(self, height=32, **kwargs):
"""Initialize user prompt window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, self.xaml_source))
self.user_height = height
self.update_window()
self._setup(**kwargs)
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `user_height = height``instance-attribute` ##### `xaml_source = 'ProgressBar.xaml'``class-attribute``instance-attribute` ##### `title``property``writable` Progress bar title. ##### `indeterminate``property``writable` Progress bar indeterminate state. #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show(modal=False)` Show window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
323
324
325
326
327
328
``` | ```md-code__content
def show(self, modal=False):
"""Show window."""
if modal:
return self.ShowDialog()
# else open non-modal
self.Show()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `update_window()` Update the prompt bar to match Revit window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
``` | ```md-code__content
def update_window(self):
"""Update the prompt bar to match Revit window."""
screen_area = HOST_APP.proc_screen_workarea
scale_factor = 1.0 / HOST_APP.proc_screen_scalefactor
top = left = width = height = 0
window_rect = revit.ui.get_window_rectangle()
# set width and height
width = window_rect.Right - window_rect.Left
height = self.user_height
top = window_rect.Top
# in maximized window, the top might be off the active screen
# due to windows thicker window frames
# lets cut the height and re-adjust the top
top_diff = abs(screen_area.Top - top)
if 10 > top_diff > 0 and top_diff < height:
height -= top_diff
top = screen_area.Top
left = window_rect.Left
# in maximized window, Left also might be off the active screen
# due to windows thicker window frames
# let's fix the width to accomodate the extra pixels as well
left_diff = abs(screen_area.Left - left)
if 10 > left_diff > 0 and left_diff < width:
# deduct two times the left negative offset since this extra
# offset happens on both left and right side
width -= left_diff * 2
left = screen_area.Left
self.Top = top * scale_factor
self.Left = left * scale_factor
self.Width = width * scale_factor
self.Height = height
``` | ##### `clicked_cancel(sender, args)` Handler for cancel button clicked event. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1674
1675
1676
1677
``` | ```md-code__content
def clicked_cancel(self, sender, args): #pylint: disable=W0613
"""Handler for cancel button clicked event."""
self.cancel_b.Content = 'Cancelling...'
self.cancelled = True #pylint: disable=W0201
``` | ##### `reset()` Reset progress value to 0. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1679
1680
1681
``` | ```md-code__content
def reset(self):
"""Reset progress value to 0."""
self.update_progress(0, 1)
``` | ##### `update_progress(new_value, max_value=1)` Update progress bar state with given min, max values. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `new_value` | `float` | current progress value | _required_ | | `max_value` | `float` | total progress value | `1` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
``` | ```md-code__content
def update_progress(self, new_value, max_value=1):
"""Update progress bar state with given min, max values.
Args:
new_value (float): current progress value
max_value (float): total progress value
"""
self.max_value = max_value #pylint: disable=W0201
self.new_value = new_value #pylint: disable=W0201
if self.new_value == 0:
self._dispatch_updater()
elif self.step > 0:
if self.new_value % self.step == 0:
self._dispatch_updater()
else:
self._dispatch_updater()
``` | ### `SearchPrompt(search_db, width, height, **kwargs)` Bases: `WPFWindow` Standard prompt for pyRevit search. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `search_db` | `list` | list of possible search targets | _required_ | | `width` | `int` | width of search prompt window | _required_ | | `height` | `int` | height of search prompt window | _required_ | Other Parameters: | Name | Type | Description | | --- | --- | --- | | `search_tip` | `str` | text to show in grayscale when search box is empty | | `switches` | `str` | list of switches | Returns: | Type | Description | | --- | --- | | `tuple[str, dict] | str` | matched string if switches are not provided,
matched strings, and dict of switches otherwise. | Examples: ```md-code__content from pyrevit import forms # assume search input of '/switch1 target1' matched_str, args, switches = forms.SearchPrompt.show( search_db=['target1', 'target2', 'target3', 'target4'], switches=['/switch1', '/switch2'], search_tip='pyRevit Search' ) matched_str 'target1' args ['--help', '--branch', 'branchname'] switches {'/switch1': True, '/switch2': False} ``` Initialize search prompt window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
``` | ```md-code__content
def __init__(self, search_db, width, height, **kwargs):
"""Initialize search prompt window."""
WPFWindow.__init__(self,
op.join(XAML_FILES_DIR, 'SearchPrompt.xaml'))
self.Width = width
self.MinWidth = self.Width
self.Height = height
self.search_tip = kwargs.get('search_tip', '')
if isinstance(search_db, list):
self._search_db = None
self._search_db_keys = search_db
elif isinstance(search_db, dict):
self._search_db = search_db
self._search_db_keys = sorted(self._search_db.keys())
else:
raise PyRevitException("Unknown search database type")
self._search_res = None
self._switches = kwargs.get('switches', [])
self._setup_response()
self.search_tb.Focus()
self.hide_element(self.tab_icon)
self.hide_element(self.return_icon)
self.search_tb.Text = ''
self.set_search_results()
``` | #### Attributes ##### `pyrevit_version``property` Active pyRevit formatted version e.g. '4.9-beta'. ##### `Width = width``instance-attribute` ##### `MinWidth = self.Width``instance-attribute` ##### `Height = height``instance-attribute` ##### `search_tip = kwargs.get('search_tip', '')``instance-attribute` ##### `search_input``property``writable` Current search input. ##### `search_input_parts``property` Current cleaned up search term. ##### `search_term``property` Current cleaned up search term. ##### `search_term_switches``property` Find matching switches in search term. ##### `search_term_args``property` Find arguments in search term. ##### `search_term_main``property` Current cleaned up search term without the listed switches. ##### `search_matches``property` List of matches for the given search term. #### Functions ##### `load_xaml(xaml_source, literal_string=False, handle_esc=True, set_owner=True)` Load the window XAML file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | The XAML content or file path to load. | _required_ | | `literal_string` | `bool` | True if `xaml_source` is content,
False if it is a path. Defaults to False. | `False` | | `handle_esc` | `bool` | Whether the ESC key should be handled.
Defaults to True. | `True` | | `set_owner` | `bool` | Whether to se the window owner.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
``` | ```md-code__content
def load_xaml(self, xaml_source, literal_string=False, handle_esc=True, set_owner=True):
"""Load the window XAML file.
Args:
xaml_source (str): The XAML content or file path to load.
literal_string (bool, optional): True if `xaml_source` is content,
False if it is a path. Defaults to False.
handle_esc (bool, optional): Whether the ESC key should be handled.
Defaults to True.
set_owner (bool, optional): Whether to se the window owner.
Defaults to True.
"""
# create new id for this window
self.window_id = coreutils.new_uuid()
if not literal_string:
wpf.LoadComponent(self, self._determine_xaml(xaml_source))
else:
wpf.LoadComponent(self, framework.StringReader(xaml_source))
# set properties
self.thread_id = framework.get_current_thread_id()
if set_owner:
self.setup_owner()
self.setup_icon()
WPFWindow.setup_resources(self)
if handle_esc:
self.setup_default_handlers()
``` | ##### `merge_resource_dict(xaml_source)` Merge a ResourceDictionary xaml file with this window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_source` | `str` | xaml file with the resource dictionary | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
243
244
245
246
247
248
249
250
251
``` | ```md-code__content
def merge_resource_dict(self, xaml_source):
"""Merge a ResourceDictionary xaml file with this window.
Args:
xaml_source (str): xaml file with the resource dictionary
"""
lang_dictionary = ResourceDictionary()
lang_dictionary.Source = Uri(xaml_source, UriKind.Absolute)
self.Resources.MergedDictionaries.Add(lang_dictionary)
``` | ##### `get_locale_string(string_name)` Get localized string. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_name` | `str` | string name | _required_ | Returns: | Type | Description | | --- | --- | | `str` | localized string | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def get_locale_string(self, string_name):
"""Get localized string.
Args:
string_name (str): string name
Returns:
(str): localized string
"""
return self.FindResource(string_name)
``` | ##### `setup_owner()` Set the window owner. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
264
265
266
267
``` | ```md-code__content
def setup_owner(self):
"""Set the window owner."""
wih = Interop.WindowInteropHelper(self)
wih.Owner = AdWindows.ComponentManager.ApplicationWindow
``` | ##### `setup_resources(wpf_ctrl)``staticmethod` Sets the WPF resources. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
``` | ```md-code__content
@staticmethod
def setup_resources(wpf_ctrl):
"""Sets the WPF resources."""
#2c3e50
wpf_ctrl.Resources['pyRevitDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50)
#23303d
wpf_ctrl.Resources['pyRevitDarkerDarkColor'] = \
Media.Color.FromArgb(0xFF, 0x23, 0x30, 0x3d)
#ffffff
wpf_ctrl.Resources['pyRevitButtonColor'] = \
Media.Color.FromArgb(0xFF, 0xff, 0xff, 0xff)
#f39c12
wpf_ctrl.Resources['pyRevitAccentColor'] = \
Media.Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12)
wpf_ctrl.Resources['pyRevitDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkColor'])
wpf_ctrl.Resources['pyRevitAccentBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitAccentColor'])
wpf_ctrl.Resources['pyRevitDarkerDarkBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitDarkerDarkColor'])
wpf_ctrl.Resources['pyRevitButtonForgroundBrush'] = \
Media.SolidColorBrush(wpf_ctrl.Resources['pyRevitButtonColor'])
wpf_ctrl.Resources['pyRevitRecognizesAccessKey'] = \
DEFAULT_RECOGNIZE_ACCESS_KEY
``` | ##### `setup_default_handlers()` Set the default handlers. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
302
303
304
``` | ```md-code__content
def setup_default_handlers(self):
"""Set the default handlers."""
self.PreviewKeyDown += self.handle_input_key #pylint: disable=E1101
``` | ##### `handle_input_key(sender, args)` Handle keyboard input and close the window on Escape. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
306
307
308
309
``` | ```md-code__content
def handle_input_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input and close the window on Escape."""
if args.Key == Input.Key.Escape:
self.Close()
``` | ##### `set_icon(icon_path)` Set window icon to given icon path. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
311
312
313
``` | ```md-code__content
def set_icon(self, icon_path):
"""Set window icon to given icon path."""
self.Icon = utils.bitmap_from_file(icon_path)
``` | ##### `setup_icon()` Setup default window icon. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
315
316
317
``` | ```md-code__content
def setup_icon(self):
"""Setup default window icon."""
self.set_icon(op.join(BIN_DIR, 'pyrevit_settings.png'))
``` | ##### `hide()` Hide window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
319
320
321
``` | ```md-code__content
def hide(self):
"""Hide window."""
self.Hide()
``` | ##### `show_dialog()` Show modal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
330
331
332
``` | ```md-code__content
def show_dialog(self):
"""Show modal window."""
return self.ShowDialog()
``` | ##### `set_image_source_file(wpf_element, image_file)``staticmethod` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
``` | ```md-code__content
@staticmethod
def set_image_source_file(wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
if not op.exists(image_file):
wpf_element.Source = \
utils.bitmap_from_file(
os.path.join(EXEC_PARAMS.command_path,
image_file)
)
else:
wpf_element.Source = utils.bitmap_from_file(image_file)
``` | ##### `set_image_source(wpf_element, image_file)` Set source file for image element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `wpf_element` | `Image` | xaml image element | _required_ | | `image_file` | `str` | image file path | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
``` | ```md-code__content
def set_image_source(self, wpf_element, image_file):
"""Set source file for image element.
Args:
wpf_element (System.Windows.Controls.Image): xaml image element
image_file (str): image file path
"""
WPFWindow.set_image_source_file(wpf_element, image_file)
``` | ##### `dispatch(func, *args, **kwargs)` Runs the function in a new thread. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `Callable` | function to run | _required_ | | `*args` | `Any` | positional arguments to pass to func | `()` | | `**kwargs` | `Any` | keyword arguments to pass to func | `{}` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
``` | ```md-code__content
def dispatch(self, func, *args, **kwargs):
"""Runs the function in a new thread.
Args:
func (Callable): function to run
*args (Any): positional arguments to pass to func
**kwargs (Any): keyword arguments to pass to func
"""
if framework.get_current_thread_id() == self.thread_id:
t = threading.Thread(
target=func,
args=args,
kwargs=kwargs
)
t.start()
else:
# ask ui thread to call the func with args and kwargs
self.Dispatcher.Invoke(
System.Action(
lambda: func(*args, **kwargs)
),
Threading.DispatcherPriority.Background
)
``` | ##### `conceal()` Conceal window. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
384
385
386
``` | ```md-code__content
def conceal(self):
"""Conceal window."""
return WindowToggler(self)
``` | ##### `hide_element(*wpf_elements)``staticmethod` Collapse elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be collaped | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
395
396
397
398
399
400
401
402
403
``` | ```md-code__content
@staticmethod
def hide_element(*wpf_elements):
"""Collapse elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be collaped
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_COLLAPSED
``` | ##### `show_element(*wpf_elements)``staticmethod` Show collapsed elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be set to visible. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
405
406
407
408
409
410
411
412
413
``` | ```md-code__content
@staticmethod
def show_element(*wpf_elements):
"""Show collapsed elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be set to visible.
"""
for wpfel in wpf_elements:
wpfel.Visibility = WPF_VISIBLE
``` | ##### `toggle_element(*wpf_elements)``staticmethod` Toggle visibility of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be toggled. | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
@staticmethod
def toggle_element(*wpf_elements):
"""Toggle visibility of elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be toggled.
"""
for wpfel in wpf_elements:
if wpfel.Visibility == WPF_VISIBLE:
WPFWindow.hide_element(wpfel)
elif wpfel.Visibility == WPF_COLLAPSED:
WPFWindow.show_element(wpfel)
``` | ##### `disable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
@staticmethod
def disable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = False
``` | ##### `enable_element(*wpf_elements)``staticmethod` Enable elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*wpf_elements` | `list[UIElement]` | WPF framework elements to be enabled | `()` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
@staticmethod
def enable_element(*wpf_elements):
"""Enable elements.
Args:
*wpf_elements (list[UIElement]): WPF framework elements to be enabled
"""
for wpfel in wpf_elements:
wpfel.IsEnabled = True
``` | ##### `handle_url_click(sender, args)` Callback for handling click on package website url. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
448
449
450
``` | ```md-code__content
def handle_url_click(self, sender, args): #pylint: disable=unused-argument
"""Callback for handling click on package website url."""
return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri)
``` | ##### `update_results_display(fill_match=False)` Update search prompt results based on current input text. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
``` | ```md-code__content
def update_results_display(self, fill_match=False):
"""Update search prompt results based on current input text."""
self.directmatch_tb.Text = ''
self.wordsmatch_tb.Text = ''
results = self.search_matches
res_cout = len(results)
mlogger.debug('unique results count: %s', res_cout)
mlogger.debug('unique results: %s', results)
if res_cout > 1:
self.show_element(self.tab_icon)
self.hide_element(self.return_icon)
elif res_cout == 1:
self.hide_element(self.tab_icon)
self.show_element(self.return_icon)
else:
self.hide_element(self.tab_icon)
self.hide_element(self.return_icon)
if self._result_index >= res_cout:
self._result_index = 0 #pylint: disable=W0201
if self._result_index < 0:
self._result_index = res_cout - 1 #pylint: disable=W0201
if not self.search_input:
self.directmatch_tb.Text = self.search_tip
return
if results:
input_term = self.search_term
cur_res = results[self._result_index]
mlogger.debug('current result: %s', cur_res)
if fill_match:
self.search_input = cur_res
else:
if cur_res.lower().startswith(input_term):
self.directmatch_tb.Text = \
self.search_input + cur_res[len(input_term):]
mlogger.debug('directmatch_tb.Text: %s',
self.directmatch_tb.Text)
else:
self.wordsmatch_tb.Text = '- {}'.format(cur_res)
mlogger.debug('wordsmatch_tb.Text: %s',
self.wordsmatch_tb.Text)
tooltip = self._search_db.get(cur_res, None)
if tooltip:
self.tooltip_tb.Text = tooltip
self.show_element(self.tooltip_tb)
else:
self.hide_element(self.tooltip_tb)
self._search_res = cur_res
return True
return False
``` | ##### `set_search_results(*args)` Set search results for returning. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
``` | ```md-code__content
def set_search_results(self, *args):
"""Set search results for returning."""
self._result_index = 0
self._search_results = []
mlogger.debug('search input: %s', self.search_input)
mlogger.debug('search term: %s', self.search_term)
mlogger.debug('search term (main): %s', self.search_term_main)
mlogger.debug('search term (parts): %s', self.search_input_parts)
mlogger.debug('search term (args): %s', self.search_term_args)
mlogger.debug('search term (switches): %s', self.search_term_switches)
for resultset in args:
mlogger.debug('result set: %s}', resultset)
self._search_results.extend(sorted(resultset))
mlogger.debug('results: %s', self._search_results)
``` | ##### `find_direct_match(input_text)` Find direct text matches in search term. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1903
1904
1905
1906
1907
1908
1909
1910
1911
``` | ```md-code__content
def find_direct_match(self, input_text):
"""Find direct text matches in search term."""
results = []
if input_text:
for cmd_name in self._search_db_keys:
if cmd_name.lower().startswith(input_text):
results.append(cmd_name)
return results
``` | ##### `find_word_match(input_text)` Find direct word matches in search term. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
``` | ```md-code__content
def find_word_match(self, input_text):
"""Find direct word matches in search term."""
results = []
if input_text:
cur_words = input_text.split(' ')
for cmd_name in self._search_db_keys:
if all([x in cmd_name.lower() for x in cur_words]):
results.append(cmd_name)
return results
``` | ##### `search_txt_changed(sender, args)` Handle text changed event. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1924
1925
1926
1927
1928
1929
1930
``` | ```md-code__content
def search_txt_changed(self, sender, args): #pylint: disable=W0613
"""Handle text changed event."""
input_term = self.search_term_main
dmresults = self.find_direct_match(input_term)
wordresults = self.find_word_match(input_term)
self.set_search_results(dmresults, wordresults)
self.update_results_display()
``` | ##### `handle_kb_key(sender, args)` Handle keyboard input event. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
``` | ```md-code__content
def handle_kb_key(self, sender, args): #pylint: disable=W0613
"""Handle keyboard input event."""
shiftdown = Input.Keyboard.IsKeyDown(Input.Key.LeftShift) \
or Input.Keyboard.IsKeyDown(Input.Key.RightShift)
# Escape: set response to none and close
if args.Key == Input.Key.Escape:
self._setup_response()
self.Close()
# Enter: close, returns matched response automatically
elif args.Key == Input.Key.Enter:
if self.search_tb.Text != '':
self._setup_response(response=self._search_res)
args.Handled = True
self.Close()
# Shift+Tab, Tab: Cycle through matches
elif args.Key == Input.Key.Tab and shiftdown:
self._result_index -= 1
self.update_results_display()
elif args.Key == Input.Key.Tab:
self._result_index += 1
self.update_results_display()
# Up, Down: Cycle through matches
elif args.Key == Input.Key.Up:
self._result_index -= 1
self.update_results_display()
elif args.Key == Input.Key.Down:
self._result_index += 1
self.update_results_display()
# Right, End: Autocomplete with displayed match
elif args.Key in [Input.Key.Right,
Input.Key.End]:
self.update_results_display(fill_match=True)
``` | ##### `show(search_db, width=DEFAULT_SEARCHWND_WIDTH, height=DEFAULT_SEARCHWND_HEIGHT, **kwargs)``classmethod` Show search prompt. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1965
1966
1967
1968
1969
1970
1971
1972
``` | ```md-code__content
@classmethod
def show(cls, search_db, #pylint: disable=W0221
width=DEFAULT_SEARCHWND_WIDTH,
height=DEFAULT_SEARCHWND_HEIGHT, **kwargs):
"""Show search prompt."""
dlg = cls(search_db, width, height, **kwargs)
dlg.ShowDialog()
return dlg.response
``` | ### `RevisionOption(revision_element)` Bases: `TemplateListItem` Revision wrapper for :func: `select_revisions`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1977
1978
``` | ```md-code__content
def __init__(self, revision_element):
super(RevisionOption, self).__init__(revision_element)
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `checkable``property``writable` List Item CheckBox Visibility. ##### `name``property` Revision name (description). #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ### `SheetOption(sheet_element)` Bases: `TemplateListItem` Sheet wrapper for :func: `select_sheets`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
1996
1997
``` | ```md-code__content
def __init__(self, sheet_element):
super(SheetOption, self).__init__(sheet_element)
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `checkable``property``writable` List Item CheckBox Visibility. ##### `name``property` Sheet name. ##### `number``property` Sheet number. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ### `ViewOption(view_element)` Bases: `TemplateListItem` View wrapper for :func: `select_views`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2015
2016
``` | ```md-code__content
def __init__(self, view_element):
super(ViewOption, self).__init__(view_element)
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `checkable``property``writable` List Item CheckBox Visibility. ##### `name``property` View name. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ### `LevelOption(level_element)` Bases: `TemplateListItem` Level wrapper for :func: `select_levels`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2027
2028
``` | ```md-code__content
def __init__(self, level_element):
super(LevelOption, self).__init__(level_element)
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `checkable``property``writable` List Item CheckBox Visibility. ##### `name``property` Level name. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ### `FamilyParamOption(fparam, builtin=False, labeled=False)` Bases: `TemplateListItem` Level wrapper for :func: `select_family_parameters`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2038
2039
2040
2041
``` | ```md-code__content
def __init__(self, fparam, builtin=False, labeled=False):
super(FamilyParamOption, self).__init__(fparam)
self.isbuiltin = builtin
self.islabeled = labeled
``` | #### Attributes ##### `item = orig_item``instance-attribute` ##### `state = checked``instance-attribute` ##### `checkable``property``writable` List Item CheckBox Visibility. ##### `isbuiltin = builtin``instance-attribute` ##### `islabeled = labeled``instance-attribute` ##### `name``property` Family Parameter name. ##### `istype``property` Is type parameter. #### Functions ##### `add_PropertyChanged(value)` Called when a property is added to the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
113
114
115
``` | ```md-code__content
def add_PropertyChanged(self, value):
"""Called when a property is added to the object."""
self.PropertyChanged += value
``` | ##### `remove_PropertyChanged(value)` Called when a property is removed from the object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def remove_PropertyChanged(self, value):
"""Called when a property is removed from the object."""
self.PropertyChanged -= value
``` | ##### `OnPropertyChanged(prop_name)` Called when a property is changed. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `prop_name` | `str` | property name | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def OnPropertyChanged(self, prop_name):
"""Called when a property is changed.
Args:
prop_name (str): property name
"""
if self._propertyChangedCaller:
args = ComponentModel.PropertyChangedEventArgs(prop_name)
self._propertyChangedCaller(self, args)
``` | ##### `unwrap()` Unwrap and return wrapped object. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
753
754
755
``` | ```md-code__content
def unwrap(self):
"""Unwrap and return wrapped object."""
return self.item
``` | ##### `checked(value)` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
762
763
764
``` | ```md-code__content
@checked.setter
def checked(self, value):
self.state = value
``` | ## Functions ### `is_registered_dockable_panel(panel_type)` Check if dockable panel is already registered. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_type` | `WPFPanel` | dockable panel type | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
568
569
570
571
572
573
574
575
576
``` | ```md-code__content
def is_registered_dockable_panel(panel_type):
"""Check if dockable panel is already registered.
Args:
panel_type (forms.WPFPanel): dockable panel type
"""
panel_uuid = coreutils.Guid.Parse(panel_type.panel_id)
dockable_panel_id = UI.DockablePaneId(panel_uuid)
return UI.DockablePane.PaneExists(dockable_panel_id)
``` | ### `register_dockable_panel(panel_type, default_visible=True)` Register dockable panel. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_type` | `WPFPanel` | dockable panel type | _required_ | | `default_visible` | `bool` | whether panel should be visible by default | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
``` | ```md-code__content
def register_dockable_panel(panel_type, default_visible=True):
"""Register dockable panel.
Args:
panel_type (forms.WPFPanel): dockable panel type
default_visible (bool, optional):
whether panel should be visible by default
"""
if not issubclass(panel_type, WPFPanel):
raise PyRevitException(
"Dockable pane must be a subclass of forms.WPFPanel"
)
panel_uuid = coreutils.Guid.Parse(panel_type.panel_id)
dockable_panel_id = UI.DockablePaneId(panel_uuid)
panel_provider = _WPFPanelProvider(panel_type, default_visible)
HOST_APP.uiapp.RegisterDockablePane(
dockable_panel_id,
panel_type.panel_title,
panel_provider
)
return panel_provider.panel
``` | ### `open_dockable_panel(panel_type_or_id)` Open previously registered dockable panel. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_type_or_id` | `(WPFPanel, str)` | panel type or id | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
604
605
606
607
608
609
610
``` | ```md-code__content
def open_dockable_panel(panel_type_or_id):
"""Open previously registered dockable panel.
Args:
panel_type_or_id (forms.WPFPanel, str): panel type or id
"""
toggle_dockable_panel(panel_type_or_id, True)
``` | ### `close_dockable_panel(panel_type_or_id)` Close previously registered dockable panel. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_type_or_id` | `(WPFPanel, str)` | panel type or id | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
613
614
615
616
617
618
619
``` | ```md-code__content
def close_dockable_panel(panel_type_or_id):
"""Close previously registered dockable panel.
Args:
panel_type_or_id (forms.WPFPanel, str): panel type or id
"""
toggle_dockable_panel(panel_type_or_id, False)
``` | ### `toggle_dockable_panel(panel_type_or_id, state)` Toggle previously registered dockable panel. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_type_or_id` | `WPFPanel | str` | panel type or id | _required_ | | `state` | `bool` | True to show the panel, False to hide it. | _required_ | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
``` | ```md-code__content
def toggle_dockable_panel(panel_type_or_id, state):
"""Toggle previously registered dockable panel.
Args:
panel_type_or_id (forms.WPFPanel | str): panel type or id
state (bool): True to show the panel, False to hide it.
"""
dpanel_id = None
if isinstance(panel_type_or_id, str):
panel_id = coreutils.Guid.Parse(panel_type_or_id)
dpanel_id = UI.DockablePaneId(panel_id)
elif issubclass(panel_type_or_id, WPFPanel):
panel_id = coreutils.Guid.Parse(panel_type_or_id.panel_id)
dpanel_id = UI.DockablePaneId(panel_id)
else:
raise PyRevitException("Given type is not a forms.WPFPanel")
if dpanel_id:
if UI.DockablePane.PaneIsRegistered(dpanel_id):
dockable_panel = HOST_APP.uiapp.GetDockablePane(dpanel_id)
if state:
dockable_panel.Show()
else:
dockable_panel.Hide()
else:
raise PyRevitException(
"Panel with id \"%s\" is not registered" % panel_type_or_id
)
``` | ### `select_revisions(title='Select Revision', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None)` Standard form for selecting revisions. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Revision'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for revisions; defaults to active document | `None` | Returns: | Type | Description | | --- | --- | | `list[Revision]` | list of selected revisions | Examples: ```md-code__content from pyrevit import forms forms.select_revisions() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
``` | ````md-code__content
def select_revisions(title='Select Revision',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None):
"""Standard form for selecting revisions.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for revisions; defaults to active document
Returns:
(list[DB.Revision]): list of selected revisions
Examples:
```python
from pyrevit import forms
forms.select_revisions()
[,
]
```
"""
doc = doc or DOCS.doc
revisions = sorted(revit.query.get_revisions(doc=doc),
key=lambda x: x.SequenceNumber)
if filterfunc:
revisions = filter(filterfunc, revisions)
# ask user for revisions
selected_revs = SelectFromList.show(
[RevisionOption(x) for x in revisions],
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)
return selected_revs
```` | ### `select_sheets(title='Select Sheets', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None, include_placeholder=True, use_selection=False)` Standard form for selecting sheets. Sheets are grouped into sheet sets and sheet set can be selected from a drop down box at the top of window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Sheets'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for sheets; defaults to active document | `None` | | `include_placeholder` | `bool` | include a placeholder.
Defaults to True | `True` | | `use_selection` | `bool` | ask if user wants to use currently selected sheets. | `False` | Returns: | Type | Description | | --- | --- | | `list[ViewSheet]` | list of selected sheets | Examples: ```md-code__content from pyrevit import forms forms.select_sheets() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
``` | ````md-code__content
def select_sheets(title='Select Sheets',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None,
include_placeholder=True,
use_selection=False):
"""Standard form for selecting sheets.
Sheets are grouped into sheet sets and sheet set can be selected from
a drop down box at the top of window.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for sheets; defaults to active document
include_placeholder (bool, optional): include a placeholder.
Defaults to True
use_selection (bool, optional):
ask if user wants to use currently selected sheets.
Returns:
(list[DB.ViewSheet]): list of selected sheets
Examples:
```python
from pyrevit import forms
forms.select_sheets()
[,
]
```
"""
doc = doc or DOCS.doc
# check for previously selected sheets
if use_selection:
current_selected_sheets = revit.get_selection() \
.include(DB.ViewSheet) \
.elements
if filterfunc:
current_selected_sheets = \
filter(filterfunc, current_selected_sheets)
if not include_placeholder:
current_selected_sheets = \
[x for x in current_selected_sheets if not x.IsPlaceholder]
if current_selected_sheets \
and ask_to_use_selected("sheets",
count=len(current_selected_sheets),
multiple=multiple):
return current_selected_sheets \
if multiple else current_selected_sheets[0]
# otherwise get all sheets and prompt for selection
all_ops = {}
all_sheets = DB.FilteredElementCollector(doc) \
.OfClass(DB.ViewSheet) \
.WhereElementIsNotElementType() \
.ToElements()
if filterfunc:
all_sheets = filter(filterfunc, all_sheets)
if not include_placeholder:
all_sheets = [x for x in all_sheets if not x.IsPlaceholder]
all_sheets_ops = sorted([SheetOption(x) for x in all_sheets],
key=lambda x: x.number)
all_ops['All Sheets'] = all_sheets_ops
sheetsets = revit.query.get_sheet_sets(doc)
for sheetset in sheetsets:
sheetset_sheets = \
[x for x in sheetset.Views if isinstance(x, DB.ViewSheet)]
if filterfunc:
sheetset_sheets = filter(filterfunc, sheetset_sheets)
sheetset_ops = sorted([SheetOption(x) for x in sheetset_sheets],
key=lambda x: x.number)
all_ops[sheetset.Name] = sheetset_ops
# ask user for multiple sheets
selected_sheets = SelectFromList.show(
all_ops,
title=title,
group_selector_title='Sheet Sets:',
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True,
default_group='All Sheets'
)
return selected_sheets
```` | ### `select_views(title='Select Views', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None, use_selection=False)` Standard form for selecting views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Views'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for views; defaults to active document | `None` | | `use_selection` | `bool` | ask if user wants to use currently selected views. | `False` | Returns: | Type | Description | | --- | --- | | `list[View]` | list of selected views | Examples: ```md-code__content from pyrevit import forms forms.select_views() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
``` | ````md-code__content
def select_views(title='Select Views',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None,
use_selection=False):
"""Standard form for selecting views.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for views; defaults to active document
use_selection (bool, optional):
ask if user wants to use currently selected views.
Returns:
(list[DB.View]): list of selected views
Examples:
```python
from pyrevit import forms
forms.select_views()
[,
]
```
"""
doc = doc or DOCS.doc
# check for previously selected sheets
if use_selection:
current_selected_views = revit.get_selection() \
.include(DB.View) \
.elements
if filterfunc:
current_selected_views = \
filter(filterfunc, current_selected_views)
if current_selected_views \
and ask_to_use_selected("views",
count=len(current_selected_views),
multiple=multiple):
return current_selected_views \
if multiple else current_selected_views[0]
# otherwise get all sheets and prompt for selection
all_graphviews = revit.query.get_all_views(doc=doc)
if filterfunc:
all_graphviews = filter(filterfunc, all_graphviews)
selected_views = SelectFromList.show(
sorted([ViewOption(x) for x in all_graphviews],
key=lambda x: x.name),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)
return selected_views
```` | ### `select_levels(title='Select Levels', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None, use_selection=False)` Standard form for selecting levels. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Levels'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for levels; defaults to active document | `None` | | `use_selection` | `bool` | ask if user wants to use currently selected levels. | `False` | Returns: | Type | Description | | --- | --- | | `list[Level]` | list of selected levels | Examples: ```md-code__content from pyrevit import forms forms.select_levels() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
``` | ````md-code__content
def select_levels(title='Select Levels',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None,
use_selection=False):
"""Standard form for selecting levels.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for levels; defaults to active document
use_selection (bool, optional):
ask if user wants to use currently selected levels.
Returns:
(list[DB.Level]): list of selected levels
Examples:
```python
from pyrevit import forms
forms.select_levels()
[,
]
```
"""
doc = doc or DOCS.doc
# check for previously selected sheets
if use_selection:
current_selected_levels = revit.get_selection() \
.include(DB.Level) \
.elements
if filterfunc:
current_selected_levels = \
filter(filterfunc, current_selected_levels)
if current_selected_levels \
and ask_to_use_selected("levels",
count=len(current_selected_levels),
multiple=multiple):
return current_selected_levels \
if multiple else current_selected_levels[0]
all_levels = \
revit.query.get_elements_by_categories(
[DB.BuiltInCategory.OST_Levels],
doc=doc
)
if filterfunc:
all_levels = filter(filterfunc, all_levels)
selected_levels = SelectFromList.show(
sorted([LevelOption(x) for x in all_levels],
key=lambda x: x.Elevation),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True,
)
return selected_levels
```` | ### `select_viewtemplates(title='Select View Templates', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None)` Standard form for selecting view templates. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select View Templates'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for views; defaults to active document | `None` | Returns: | Type | Description | | --- | --- | | `list[View]` | list of selected view templates | Examples: ```md-code__content from pyrevit import forms forms.select_viewtemplates() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
``` | ````md-code__content
def select_viewtemplates(title='Select View Templates',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None):
"""Standard form for selecting view templates.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for views; defaults to active document
Returns:
(list[DB.View]): list of selected view templates
Examples:
```python
from pyrevit import forms
forms.select_viewtemplates()
[,
]
```
"""
doc = doc or DOCS.doc
all_viewtemplates = revit.query.get_all_view_templates(doc=doc)
if filterfunc:
all_viewtemplates = filter(filterfunc, all_viewtemplates)
selected_viewtemplates = SelectFromList.show(
sorted([ViewOption(x) for x in all_viewtemplates],
key=lambda x: x.name),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)
return selected_viewtemplates
```` | ### `select_schedules(title='Select Schedules', button_name='Select', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, filterfunc=None, doc=None)` Standard form for selecting schedules. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Schedules'` | | `button_name` | `str` | list window button caption | `'Select'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for views; defaults to active document | `None` | Returns: | Type | Description | | --- | --- | | `list[ViewSchedule]` | list of selected schedules | Examples: ```md-code__content from pyrevit import forms forms.select_schedules() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
``` | ````md-code__content
def select_schedules(title='Select Schedules',
button_name='Select',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=True,
filterfunc=None,
doc=None):
"""Standard form for selecting schedules.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for views; defaults to active document
Returns:
(list[DB.ViewSchedule]): list of selected schedules
Examples:
```python
from pyrevit import forms
forms.select_schedules()
[,
]
```
"""
doc = doc or DOCS.doc
all_schedules = revit.query.get_all_schedules(doc=doc)
if filterfunc:
all_schedules = filter(filterfunc, all_schedules)
selected_schedules = \
SelectFromList.show(
sorted([ViewOption(x) for x in all_schedules],
key=lambda x: x.name),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
checked_only=True
)
return selected_schedules
```` | ### `select_open_docs(title='Select Open Documents', button_name='OK', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=True, check_more_than_one=True, filterfunc=None)` Standard form for selecting open documents. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Open Documents'` | | `button_name` | `str` | list window button caption | `'OK'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `check_more_than_one` | `bool` | | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | Returns: | Type | Description | | --- | --- | | `list[Document]` | list of selected documents | Examples: ```md-code__content from pyrevit import forms forms.select_open_docs() [,\ ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
``` | ````md-code__content
def select_open_docs(title='Select Open Documents',
button_name='OK',
width=DEFAULT_INPUTWINDOW_WIDTH, #pylint: disable=W0613
multiple=True,
check_more_than_one=True,
filterfunc=None):
"""Standard form for selecting open documents.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to True
check_more_than_one (bool, optional):
filterfunc (function):
filter function to be applied to context items.
Returns:
(list[DB.Document]): list of selected documents
Examples:
```python
from pyrevit import forms
forms.select_open_docs()
[,
]
```
"""
# find open documents other than the active doc
open_docs = [d for d in revit.docs if not d.IsLinked] #pylint: disable=E1101
if check_more_than_one:
open_docs.remove(revit.doc) #pylint: disable=E1101
if not open_docs:
alert('Only one active document is found. '
'At least two documents must be open. '
'Operation cancelled.')
return
return SelectFromList.show(
open_docs,
name_attr='Title',
multiselect=multiple,
title=title,
button_name=button_name,
filterfunc=filterfunc
)
```` | ### `select_titleblocks(title='Select Titleblock', button_name='Select', no_tb_option='No Title Block', width=DEFAULT_INPUTWINDOW_WIDTH, multiple=False, filterfunc=None, doc=None)` Standard form for selecting a titleblock. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | list window title | `'Select Titleblock'` | | `button_name` | `str` | list window button caption | `'Select'` | | `no_tb_option` | `str` | name of option for no title block | `'No Title Block'` | | `width` | `int` | width of list window | `DEFAULT_INPUTWINDOW_WIDTH` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to False | `False` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `doc` | `Document` | source document for titleblocks; defaults to active document | `None` | Returns: | Type | Description | | --- | --- | | `ElementId` | selected titleblock id. | Examples: ```md-code__content from pyrevit import forms forms.select_titleblocks() ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
``` | ````md-code__content
def select_titleblocks(title='Select Titleblock',
button_name='Select',
no_tb_option='No Title Block',
width=DEFAULT_INPUTWINDOW_WIDTH,
multiple=False,
filterfunc=None,
doc=None):
"""Standard form for selecting a titleblock.
Args:
title (str, optional): list window title
button_name (str, optional): list window button caption
no_tb_option (str, optional): name of option for no title block
width (int, optional): width of list window
multiple (bool, optional):
allow multi-selection (uses check boxes). defaults to False
filterfunc (function):
filter function to be applied to context items.
doc (DB.Document, optional):
source document for titleblocks; defaults to active document
Returns:
(DB.ElementId): selected titleblock id.
Examples:
```python
from pyrevit import forms
forms.select_titleblocks()

```
"""
doc = doc or DOCS.doc
titleblocks = DB.FilteredElementCollector(doc)\
.OfCategory(DB.BuiltInCategory.OST_TitleBlocks)\
.WhereElementIsElementType()\
.ToElements()
tblock_dict = {'{}: {}'.format(tb.FamilyName,
revit.query.get_name(tb)): tb.Id
for tb in titleblocks}
tblock_dict[no_tb_option] = DB.ElementId.InvalidElementId
selected_titleblocks = SelectFromList.show(sorted(tblock_dict.keys()),
title=title,
button_name=button_name,
width=width,
multiselect=multiple,
filterfunc=filterfunc)
if selected_titleblocks:
if multiple:
return [tblock_dict[x] for x in selected_titleblocks]
else:
return tblock_dict[selected_titleblocks]
```` | ### `select_swatch(title='Select Color Swatch', button_name='Select')` Standard form for selecting a color swatch. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | swatch list window title | `'Select Color Swatch'` | | `button_name` | `str` | swatch list window button caption | `'Select'` | Returns: | Type | Description | | --- | --- | | `RGB` | rgb color | Examples: ```md-code__content from pyrevit import forms forms.select_swatch(title="Select Text Color") ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
``` | ````md-code__content
def select_swatch(title='Select Color Swatch', button_name='Select'):
"""Standard form for selecting a color swatch.
Args:
title (str, optional): swatch list window title
button_name (str, optional): swatch list window button caption
Returns:
(pyrevit.coreutils.colors.RGB): rgb color
Examples:
```python
from pyrevit import forms
forms.select_swatch(title="Select Text Color")

```
"""
itemplate = utils.load_ctrl_template(
os.path.join(XAML_FILES_DIR, "SwatchContainerStyle.xaml")
)
swatch = SelectFromList.show(
colors.COLORS.values(),
title=title,
button_name=button_name,
width=300,
multiselect=False,
item_template=itemplate
)
return swatch
```` | ### `select_image(images, title='Select Image', button_name='Select')` Standard form for selecting an image. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `images` | `list[str] | list[BitmapImage]` | list of image file paths or bitmaps | _required_ | | `title` | `str` | swatch list window title | `'Select Image'` | | `button_name` | `str` | swatch list window button caption | `'Select'` | Returns: | Type | Description | | --- | --- | | `str` | path of the selected image | Examples: ```md-code__content from pyrevit import forms forms.select_image(['C:/path/to/image1.png',\ 'C:/path/to/image2.png'], title="Select Variation") 'C:/path/to/image1.png' ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
``` | ````md-code__content
def select_image(images, title='Select Image', button_name='Select'):
"""Standard form for selecting an image.
Args:
images (list[str] | list[framework.Imaging.BitmapImage]):
list of image file paths or bitmaps
title (str, optional): swatch list window title
button_name (str, optional): swatch list window button caption
Returns:
(str): path of the selected image
Examples:
```python
from pyrevit import forms
forms.select_image(['C:/path/to/image1.png',
'C:/path/to/image2.png'],
title="Select Variation")
'C:/path/to/image1.png'
```
"""
ptemplate = utils.load_itemspanel_template(
os.path.join(XAML_FILES_DIR, "ImageListPanelStyle.xaml")
)
itemplate = utils.load_ctrl_template(
os.path.join(XAML_FILES_DIR, "ImageListContainerStyle.xaml")
)
bitmap_images = {}
for imageobj in images:
if isinstance(imageobj, str):
img = utils.bitmap_from_file(imageobj)
if img:
bitmap_images[img] = imageobj
elif isinstance(imageobj, framework.Imaging.BitmapImage):
bitmap_images[imageobj] = imageobj
selected_image = SelectFromList.show(
sorted(bitmap_images.keys(), key=lambda x: x.UriSource.AbsolutePath),
title=title,
button_name=button_name,
width=500,
multiselect=False,
item_template=itemplate,
items_panel_template=ptemplate
)
return bitmap_images.get(selected_image, None)
```` | ### `select_parameters(src_element, title='Select Parameters', button_name='Select', multiple=True, filterfunc=None, include_instance=True, include_type=True, exclude_readonly=True)` Standard form for selecting parameters from given element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `src_element` | `Element` | source element | _required_ | | `title` | `str` | list window title | `'Select Parameters'` | | `button_name` | `str` | list window button caption | `'Select'` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `include_instance` | `bool` | list instance parameters | `True` | | `include_type` | `bool` | list type parameters | `True` | | `exclude_readonly` | `bool` | only shows parameters that are editable | `True` | Returns: | Type | Description | | --- | --- | | `list[ParamDef]` | list of paramdef objects | Examples: ```md-code__content forms.select_parameter( src_element, title='Select Parameters', multiple=True, include_instance=True, include_type=True ) [, ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
``` | ````md-code__content
def select_parameters(src_element,
title='Select Parameters',
button_name='Select',
multiple=True,
filterfunc=None,
include_instance=True,
include_type=True,
exclude_readonly=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
multiple (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
exclude_readonly (bool, optional): only shows parameters that are editable
Returns:
(list[ParamDef]): list of paramdef objects
Examples:
```python
forms.select_parameter(
src_element,
title='Select Parameters',
multiple=True,
include_instance=True,
include_type=True
)
[, ]
```
"""
param_defs = []
non_storage_type = coreutils.get_enum_none(DB.StorageType)
if include_instance:
# collect instance parameters
param_defs.extend(
[ParamDef(name=x.Definition.Name,
istype=False,
definition=x.Definition,
isreadonly=x.IsReadOnly)
for x in src_element.Parameters
if x.StorageType != non_storage_type]
)
if include_type:
# collect type parameters
src_type = revit.query.get_type(src_element) if src_element else None
if src_type is not None:
param_defs.extend(
[ParamDef(name=x.Definition.Name,
istype=True,
definition=x.Definition,
isreadonly=x.IsReadOnly)
for x in src_type.Parameters
if x.StorageType != non_storage_type]
)
if exclude_readonly:
param_defs = filter(lambda x: not x.isreadonly, param_defs)
if filterfunc:
param_defs = filter(filterfunc, param_defs)
param_defs.sort(key=lambda x: x.name)
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
```` | ### `select_family_parameters(family_doc, title='Select Parameters', button_name='Select', multiple=True, filterfunc=None, include_instance=True, include_type=True, include_builtin=True, include_labeled=True)` Standard form for selecting parameters from given family document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_doc` | `Document` | source family document | _required_ | | `title` | `str` | list window title | `'Select Parameters'` | | `button_name` | `str` | list window button caption | `'Select'` | | `multiple` | `bool` | allow multi-selection (uses check boxes). defaults to True | `True` | | `filterfunc` | `function` | filter function to be applied to context items. | `None` | | `include_instance` | `bool` | list instance parameters | `True` | | `include_type` | `bool` | list type parameters | `True` | | `include_builtin` | `bool` | list builtin parameters | `True` | | `include_labeled` | `bool` | list parameters used as labels | `True` | Returns: | Type | Description | | --- | --- | | `list[FamilyParameter]` | list of family parameter objects | Examples: ```md-code__content forms.select_family_parameters( family_doc, title='Select Parameters', multiple=True, include_instance=True, include_type=True ) [, ] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
``` | ````md-code__content
def select_family_parameters(family_doc,
title='Select Parameters',
button_name='Select',
multiple=True,
filterfunc=None,
include_instance=True,
include_type=True,
include_builtin=True,
include_labeled=True):
"""Standard form for selecting parameters from given family document.
Args:
family_doc (DB.Document): source family document
title (str, optional): list window title
button_name (str, optional): list window button caption
multiple (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
include_builtin (bool, optional): list builtin parameters
include_labeled (bool, optional): list parameters used as labels
Returns:
(list[DB.FamilyParameter]): list of family parameter objects
Examples:
```python
forms.select_family_parameters(
family_doc,
title='Select Parameters',
multiple=True,
include_instance=True,
include_type=True
)
[, ]
```
"""
family_doc = family_doc or DOCS.doc
family_params = revit.query.get_family_parameters(family_doc)
# get all params used in labeles
label_param_ids = \
[x.Id for x in revit.query.get_family_label_parameters(family_doc)]
if filterfunc:
family_params = filter(filterfunc, family_params)
param_defs = []
get_elementid_value = get_elementid_value_func()
for family_param in family_params:
if not include_instance and family_param.IsInstance:
continue
if not include_type and not family_param.IsInstance:
continue
if not include_builtin and get_elementid_value(family_param.Id) < 0:
continue
if not include_labeled and family_param.Id in label_param_ids:
continue
param_defs.append(
FamilyParamOption(family_param,
builtin=get_elementid_value(family_param.Id) < 0,
labeled=family_param.Id in label_param_ids)
)
param_defs.sort(key=lambda x: x.name)
itemplate = utils.load_ctrl_template(
os.path.join(XAML_FILES_DIR, "FamilyParameterItemStyle.xaml")
)
selected_params = SelectFromList.show(
{
'All Parameters': param_defs,
'Type Parameters': [x for x in param_defs if x.istype],
'Built-in Parameters': [x for x in param_defs if x.isbuiltin],
'Used as Label': [x for x in param_defs if x.islabeled],
},
title=title,
button_name=button_name,
group_selector_title='Parameter Filters:',
width=450,
multiselect=multiple,
item_template=itemplate
)
return selected_params
```` | ### `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)` Show a task dialog with given message. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `msg` | `str` | message to be displayed | _required_ | | `title` | `str` | task dialog title | `None` | | `sub_msg` | `str` | sub message, use html to create clickable links | `None` | | `expanded` | `str` | expanded area message | `None` | | `footer` | `str` | footer text | `''` | | `ok` | `bool` | show OK button, defaults to True | `True` | | `cancel` | `bool` | show Cancel button, defaults to False | `False` | | `yes` | `bool` | show Yes button, defaults to False | `False` | | `no` | `bool` | show NO button, defaults to False | `False` | | `retry` | `bool` | show Retry button, defaults to False | `False` | | `warn_icon` | `bool` | show warning icon | `True` | | `options` | `list[str]` | list of command link titles in order | `None` | | `exitscript` | `bool` | exit if cancel or no, defaults to False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if okay, yes, or retry, otherwise False | Examples: ```md-code__content from pyrevit import forms forms.alert('Are you sure?', sub_msg='Click here if you are not sure and want to go to the pyRevit Forum', ok=False, yes=True, no=True, exitscript=True) ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
``` | ````md-code__content
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):
r"""Show a task dialog with given message.
Args:
msg (str): message to be displayed
title (str, optional): task dialog title
sub_msg (str, optional): sub message, use html to create clickable links
expanded (str, optional): expanded area message
footer (str, optional): footer text
ok (bool, optional): show OK button, defaults to True
cancel (bool, optional): show Cancel button, defaults to False
yes (bool, optional): show Yes button, defaults to False
no (bool, optional): show NO button, defaults to False
retry (bool, optional): show Retry button, defaults to False
warn_icon (bool, optional): show warning icon
options (list[str], optional): list of command link titles in order
exitscript (bool, optional): exit if cancel or no, defaults to False
Returns:
(bool): True if okay, yes, or retry, otherwise False
Examples:
```python
from pyrevit import forms
forms.alert('Are you sure?',
sub_msg='Click here if you are not sure and want to go to the pyRevit Forum',
ok=False, yes=True, no=True, exitscript=True)
```
"""
# BUILD DIALOG
cmd_name = EXEC_PARAMS.command_name
if not title:
title = cmd_name if cmd_name else 'pyRevit'
tdlg = UI.TaskDialog(title)
# process input types
just_ok = ok and not any([cancel, yes, no, retry])
options = options or []
# add command links if any
if options:
clinks = coreutils.get_enum_values(UI.TaskDialogCommandLinkId)
max_clinks = len(clinks)
for idx, cmd in enumerate(options):
if idx < max_clinks:
tdlg.AddCommandLink(clinks[idx], cmd)
# otherwise add buttons
else:
buttons = coreutils.get_enum_none(UI.TaskDialogCommonButtons)
if yes:
buttons |= UI.TaskDialogCommonButtons.Yes
elif ok:
buttons |= UI.TaskDialogCommonButtons.Ok
if cancel:
buttons |= UI.TaskDialogCommonButtons.Cancel
if no:
buttons |= UI.TaskDialogCommonButtons.No
if retry:
buttons |= UI.TaskDialogCommonButtons.Retry
tdlg.CommonButtons = buttons
# set texts
tdlg.MainInstruction = msg
tdlg.MainContent = sub_msg
tdlg.ExpandedContent = expanded
if footer:
footer = footer.strip() + '\n'
tdlg.FooterText = footer + 'pyRevit {}'.format(
versionmgr.get_pyrevit_version().get_formatted()
)
tdlg.TitleAutoPrefix = False
# set icon
tdlg.MainIcon = \
UI.TaskDialogIcon.TaskDialogIconWarning \
if warn_icon else UI.TaskDialogIcon.TaskDialogIconNone
# tdlg.VerificationText = 'verif'
# SHOW DIALOG
res = tdlg.Show()
# PROCESS REPONSES
# positive response
mlogger.debug('alert result: %s', res)
if res == UI.TaskDialogResult.Ok \
or res == UI.TaskDialogResult.Yes \
or res == UI.TaskDialogResult.Retry:
if just_ok and exitscript:
sys.exit()
return True
# negative response
elif res == coreutils.get_enum_none(UI.TaskDialogResult) \
or res == UI.TaskDialogResult.Cancel \
or res == UI.TaskDialogResult.No:
if exitscript:
sys.exit()
else:
return False
# command link response
elif 'CommandLink' in str(res):
tdresults = sorted(
[x for x in coreutils.get_enum_values(UI.TaskDialogResult)
if 'CommandLink' in str(x)]
)
residx = tdresults.index(res)
return options[residx]
elif exitscript:
sys.exit()
else:
return False
```` | ### `alert_ifnot(condition, msg, *args, **kwargs)` Show a task dialog with given message if condition is NOT met. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `condition` | `bool` | condition to test | _required_ | | `msg` | `str` | message to be displayed | _required_ | | `*args` | `Any` | additional arguments | `()` | | `**kwargs` | `Any` | additional keyword arguments | `{}` | Other Parameters: | Name | Type | Description | | --- | --- | --- | | `title` | `str` | task dialog title | | `ok` | `bool` | show OK button, defaults to True | | `cancel` | `bool` | show Cancel button, defaults to False | | `yes` | `bool` | show Yes button, defaults to False | | `no` | `bool` | show NO button, defaults to False | | `retry` | `bool` | show Retry button, defaults to False | | `exitscript` | `bool` | exit if cancel or no, defaults to False | Returns: | Type | Description | | --- | --- | | `bool` | True if okay, yes, or retry, otherwise False | Examples: ```md-code__content from pyrevit import forms forms.alert_ifnot(value > 12, 'Are you sure?', ok=False, yes=True, no=True, exitscript=True) ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
``` | ````md-code__content
def alert_ifnot(condition, msg, *args, **kwargs):
"""Show a task dialog with given message if condition is NOT met.
Args:
condition (bool): condition to test
msg (str): message to be displayed
*args (Any): additional arguments
**kwargs (Any): additional keyword arguments
Keyword Args:
title (str, optional): task dialog title
ok (bool, optional): show OK button, defaults to True
cancel (bool, optional): show Cancel button, defaults to False
yes (bool, optional): show Yes button, defaults to False
no (bool, optional): show NO button, defaults to False
retry (bool, optional): show Retry button, defaults to False
exitscript (bool, optional): exit if cancel or no, defaults to False
Returns:
(bool): True if okay, yes, or retry, otherwise False
Examples:
```python
from pyrevit import forms
forms.alert_ifnot(value > 12,
'Are you sure?',
ok=False, yes=True, no=True, exitscript=True)
```
"""
if not condition:
return alert(msg, *args, **kwargs)
```` | ### `pick_folder(title=None, owner=None)` Show standard windows pick folder dialog. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | title for the window | `None` | | `owner` | `object` | owner of the dialog | `None` | Returns: | Type | Description | | --- | --- | | `str` | folder path | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
``` | ```md-code__content
def pick_folder(title=None, owner=None):
"""Show standard windows pick folder dialog.
Args:
title (str, optional): title for the window
owner (object, optional): owner of the dialog
Returns:
(str): folder path
"""
if CPDialogs:
fb_dlg = CPDialogs.CommonOpenFileDialog()
fb_dlg.IsFolderPicker = True
if title:
fb_dlg.Title = title
res = CPDialogs.CommonFileDialogResult.Cancel
if owner:
res = fb_dlg.ShowDialog(owner)
else:
res = fb_dlg.ShowDialog()
if res == CPDialogs.CommonFileDialogResult.Ok:
return fb_dlg.FileName
else:
fb_dlg = Forms.FolderBrowserDialog()
if title:
fb_dlg.Description = title
if fb_dlg.ShowDialog() == Forms.DialogResult.OK:
return fb_dlg.SelectedPath
``` | ### `result_item_result_clicked(sender, e, debug=False)` Callback for a result item click event. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
2993
2994
2995
2996
2997
``` | ```md-code__content
def result_item_result_clicked(sender, e, debug=False):
"""Callback for a result item click event."""
if debug:
print("Result clicked") # using print_md here will break the script
pass
``` | ### `show_balloon(header, text, tooltip='', group='', is_favourite=False, is_new=False, timestamp=None, click_result=result_item_result_clicked)` Show ballon in the info center section. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `header` | `str` | Category section (Bold) | _required_ | | `text` | `str` | Title section (Regular) | _required_ | | `tooltip` | `str` | Tooltip | `''` | | `group` | `str` | Group | `''` | | `is_favourite` | `bool` | Add a blue star before header | `False` | | `is_new` | `bool` | Flag to new | `False` | | `timestamp` | `str` | Set timestamp | `None` | | `click_result` | `def` | Executed after a click event | `result_item_result_clicked` | Examples: ```md-code__content from pyrevit import forms date = '2019-01-01 00:00:00' date = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S') forms.show_balloon("my header", "Lorem ipsum", tooltip='tooltip', group='group', is_favourite=True, is_new=True, timestamp = date, click_result = forms.result_item_result_clicked) ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
``` | ````md-code__content
def show_balloon(header, text, tooltip='', group='', is_favourite=False, is_new=False, timestamp=None, click_result=result_item_result_clicked):
r"""Show ballon in the info center section.
Args:
header (str): Category section (Bold)
text (str): Title section (Regular)
tooltip (str): Tooltip
group (str): Group
is_favourite (bool): Add a blue star before header
is_new (bool): Flag to new
timestamp (str): Set timestamp
click_result (def): Executed after a click event
Examples:
```python
from pyrevit import forms
date = '2019-01-01 00:00:00'
date = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
forms.show_balloon("my header", "Lorem ipsum", tooltip='tooltip', group='group', is_favourite=True, is_new=True, timestamp = date, click_result = forms.result_item_result_clicked)
```
"""
result_item = Autodesk.Internal.InfoCenter.ResultItem()
result_item.Category = header
result_item.Title = text
result_item.TooltipText = tooltip
result_item.Group = group
result_item.IsFavorite = is_favourite
result_item.IsNew = is_new
if timestamp:
result_item.Timestamp = timestamp
result_item.ResultClicked += click_result
balloon = Autodesk.Windows.ComponentManager.InfoCenterPaletteManager.ShowBalloon(
result_item)
return balloon
```` | ### `pick_file(file_ext='*', files_filter='', init_dir='', restore_dir=True, multi_file=False, unc_paths=False, title=None)` Pick file dialog to select a destination file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | file extension | `'*'` | | `files_filter` | `str` | file filter | `''` | | `init_dir` | `str` | initial directory | `''` | | `restore_dir` | `bool` | restore last directory | `True` | | `multi_file` | `bool` | allow select multiple files | `False` | | `unc_paths` | `bool` | return unc paths | `False` | | `title` | `str` | text to show in the title bar | `None` | Returns: | Type | Description | | --- | --- | | `str | list[str]` | file path or list of file paths if multi\_file=True | Examples: ```md-code__content from pyrevit import forms forms.pick_file(file_ext='csv') r'C:\output\somefile.csv' ``` ```md-code__content forms.pick_file(file_ext='csv', multi_file=True) [r'C:\output\somefile1.csv', r'C:\output\somefile2.csv'] ``` ```md-code__content forms.pick_file(files_filter='All Files (*.*)|*.*|' 'Excel Workbook (*.xlsx)|*.xlsx|' 'Excel 97-2003 Workbook|*.xls', multi_file=True) [r'C:\output\somefile1.xlsx', r'C:\output\somefile2.xls'] ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
``` | ````md-code__content
def pick_file(file_ext='*', files_filter='', init_dir='',
restore_dir=True, multi_file=False, unc_paths=False, title=None):
r"""Pick file dialog to select a destination file.
Args:
file_ext (str): file extension
files_filter (str): file filter
init_dir (str): initial directory
restore_dir (bool): restore last directory
multi_file (bool): allow select multiple files
unc_paths (bool): return unc paths
title (str): text to show in the title bar
Returns:
(str | list[str]): file path or list of file paths if multi_file=True
Examples:
```python
from pyrevit import forms
forms.pick_file(file_ext='csv')
r'C:\output\somefile.csv'
```
```python
forms.pick_file(file_ext='csv', multi_file=True)
[r'C:\output\somefile1.csv', r'C:\output\somefile2.csv']
```
```python
forms.pick_file(files_filter='All Files (*.*)|*.*|'
'Excel Workbook (*.xlsx)|*.xlsx|'
'Excel 97-2003 Workbook|*.xls',
multi_file=True)
[r'C:\output\somefile1.xlsx', r'C:\output\somefile2.xls']
```
"""
of_dlg = Forms.OpenFileDialog()
if files_filter:
of_dlg.Filter = files_filter
else:
of_dlg.Filter = '|*.{}'.format(file_ext)
of_dlg.RestoreDirectory = restore_dir
of_dlg.Multiselect = multi_file
if init_dir:
of_dlg.InitialDirectory = init_dir
if title:
of_dlg.Title = title
if of_dlg.ShowDialog() == Forms.DialogResult.OK:
if multi_file:
if unc_paths:
return [coreutils.dletter_to_unc(x)
for x in of_dlg.FileNames]
return of_dlg.FileNames
else:
if unc_paths:
return coreutils.dletter_to_unc(of_dlg.FileName)
return of_dlg.FileName
```` | ### `save_file(file_ext='', files_filter='', init_dir='', default_name='', restore_dir=True, unc_paths=False, title=None)` Save file dialog to select a destination file for data. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | file extension | `''` | | `files_filter` | `str` | file filter | `''` | | `init_dir` | `str` | initial directory | `''` | | `default_name` | `str` | default file name | `''` | | `restore_dir` | `bool` | restore last directory | `True` | | `unc_paths` | `bool` | return unc paths | `False` | | `title` | `str` | text to show in the title bar | `None` | Returns: | Type | Description | | --- | --- | | `str` | file path | Examples: ```md-code__content from pyrevit import forms forms.save_file(file_ext='csv') r'C:\output\somefile.csv' ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
``` | ````md-code__content
def save_file(file_ext='', files_filter='', init_dir='', default_name='',
restore_dir=True, unc_paths=False, title=None):
r"""Save file dialog to select a destination file for data.
Args:
file_ext (str): file extension
files_filter (str): file filter
init_dir (str): initial directory
default_name (str): default file name
restore_dir (bool): restore last directory
unc_paths (bool): return unc paths
title (str): text to show in the title bar
Returns:
(str): file path
Examples:
```python
from pyrevit import forms
forms.save_file(file_ext='csv')
r'C:\output\somefile.csv'
```
"""
sf_dlg = Forms.SaveFileDialog()
if files_filter:
sf_dlg.Filter = files_filter
else:
sf_dlg.Filter = '|*.{}'.format(file_ext)
sf_dlg.RestoreDirectory = restore_dir
if init_dir:
sf_dlg.InitialDirectory = init_dir
if title:
sf_dlg.Title = title
# setting default filename
sf_dlg.FileName = default_name
if sf_dlg.ShowDialog() == Forms.DialogResult.OK:
if unc_paths:
return coreutils.dletter_to_unc(sf_dlg.FileName)
return sf_dlg.FileName
```` | ### `pick_excel_file(save=False, title=None)` File pick/save dialog for an excel file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `save` | `bool` | show file save dialog, instead of file pick dialog | `False` | | `title` | `str` | text to show in the title bar | `None` | Returns: | Type | Description | | --- | --- | | `str` | file path | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
``` | ```md-code__content
def pick_excel_file(save=False, title=None):
"""File pick/save dialog for an excel file.
Args:
save (bool): show file save dialog, instead of file pick dialog
title (str): text to show in the title bar
Returns:
(str): file path
"""
if save:
return save_file(file_ext='xlsx')
return pick_file(files_filter='Excel Workbook (*.xlsx)|*.xlsx|'
'Excel 97-2003 Workbook|*.xls',
title=title)
``` | ### `save_excel_file(title=None)` File save dialog for an excel file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `title` | `str` | text to show in the title bar | `None` | Returns: | Type | Description | | --- | --- | | `str` | file path | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
``` | ```md-code__content
def save_excel_file(title=None):
"""File save dialog for an excel file.
Args:
title (str): text to show in the title bar
Returns:
(str): file path
"""
return pick_excel_file(save=True, title=title)
``` | ### `check_workshared(doc=None, message='Model is not workshared.')` Verify if model is workshared and notify user if not. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | target document, current of not provided | `None` | | `message` | `str` | prompt message if returning False | `'Model is not workshared.'` | Returns: | Type | Description | | --- | --- | | `bool` | True if doc is workshared | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
``` | ```md-code__content
def check_workshared(doc=None, message='Model is not workshared.'):
"""Verify if model is workshared and notify user if not.
Args:
doc (DB.Document): target document, current of not provided
message (str): prompt message if returning False
Returns:
(bool): True if doc is workshared
"""
doc = doc or DOCS.doc
if not doc.IsWorkshared:
alert(message, warn_icon=True)
return False
return True
``` | ### `check_selection(exitscript=False, message='At least one element must be selected.')` Verify if selection is not empty notify user if it is. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `exitscript` | `bool` | exit script if returning False | `False` | | `message` | `str` | prompt message if returning False | `'At least one element must be selected.'` | Returns: | Type | Description | | --- | --- | | `bool` | True if selection has at least one item | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
``` | ```md-code__content
def check_selection(exitscript=False,
message='At least one element must be selected.'):
"""Verify if selection is not empty notify user if it is.
Args:
exitscript (bool): exit script if returning False
message (str): prompt message if returning False
Returns:
(bool): True if selection has at least one item
"""
if revit.get_selection().is_empty:
alert(message, exitscript=exitscript)
return False
return True
``` | ### `check_familydoc(doc=None, family_cat=None, exitscript=False)` Verify document is a Family and notify user if not. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | target document, current of not provided | `None` | | `family_cat` | `str` | family category name | `None` | | `exitscript` | `bool` | exit script if returning False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if doc is a Family and of provided category | Examples: ```md-code__content from pyrevit import forms forms.check_familydoc(doc=revit.doc, family_cat='Data Devices') True ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
``` | ````md-code__content
def check_familydoc(doc=None, family_cat=None, exitscript=False):
"""Verify document is a Family and notify user if not.
Args:
doc (DB.Document): target document, current of not provided
family_cat (str): family category name
exitscript (bool): exit script if returning False
Returns:
(bool): True if doc is a Family and of provided category
Examples:
```python
from pyrevit import forms
forms.check_familydoc(doc=revit.doc, family_cat='Data Devices')
True
```
"""
doc = doc or DOCS.doc
family_cat = revit.query.get_category(family_cat)
if doc.IsFamilyDocument and family_cat:
if doc.OwnerFamily.FamilyCategory.Id == family_cat.Id:
return True
elif doc.IsFamilyDocument and not family_cat:
return True
family_type_msg = ' of type {}'\
.format(family_cat.Name) if family_cat else''
alert('Active document must be a Family document{}.'
.format(family_type_msg), exitscript=exitscript)
return False
```` | ### `check_modeldoc(doc=None, exitscript=False)` Verify document is a not a Model and notify user if not. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | target document, current of not provided | `None` | | `exitscript` | `bool` | exit script if returning False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if doc is a Model | Examples: ```md-code__content from pyrevit import forms forms.check_modeldoc(doc=revit.doc) True ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
``` | ````md-code__content
def check_modeldoc(doc=None, exitscript=False):
"""Verify document is a not a Model and notify user if not.
Args:
doc (DB.Document): target document, current of not provided
exitscript (bool): exit script if returning False
Returns:
(bool): True if doc is a Model
Examples:
```python
from pyrevit import forms
forms.check_modeldoc(doc=revit.doc)
True
```
"""
doc = doc or DOCS.doc
if not doc.IsFamilyDocument:
return True
alert('Active document must be a Revit model (not a Family).',
exitscript=exitscript)
return False
```` | ### `check_modelview(view, exitscript=False)` Verify target view is a model view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | target view | _required_ | | `exitscript` | `bool` | exit script if returning False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if view is model view | Examples: ```md-code__content from pyrevit import forms forms.check_modelview(view=revit.active_view) True ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
``` | ````md-code__content
def check_modelview(view, exitscript=False):
"""Verify target view is a model view.
Args:
view (DB.View): target view
exitscript (bool): exit script if returning False
Returns:
(bool): True if view is model view
Examples:
```python
from pyrevit import forms
forms.check_modelview(view=revit.active_view)
True
```
"""
if not isinstance(view, (DB.View3D, DB.ViewPlan, DB.ViewSection)):
alert("Active view must be a model view.", exitscript=exitscript)
return False
return True
```` | ### `check_viewtype(view, view_type, exitscript=False)` Verify target view is of given type. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | target view | _required_ | | `view_type` | `ViewType` | type of view | _required_ | | `exitscript` | `bool` | exit script if returning False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if view is of given type | Examples: ```md-code__content from pyrevit import forms forms.check_viewtype(revit.active_view, DB.ViewType.DrawingSheet) True ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
``` | ````md-code__content
def check_viewtype(view, view_type, exitscript=False):
"""Verify target view is of given type.
Args:
view (DB.View): target view
view_type (DB.ViewType): type of view
exitscript (bool): exit script if returning False
Returns:
(bool): True if view is of given type
Examples:
```python
from pyrevit import forms
forms.check_viewtype(revit.active_view, DB.ViewType.DrawingSheet)
True
```
"""
if view.ViewType != view_type:
alert(
"Active view must be a {}.".format(
' '.join(coreutils.split_words(str(view_type)))),
exitscript=exitscript
)
return False
return True
```` | ### `check_graphicalview(view, exitscript=False)` Verify target view is a graphical view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | target view | _required_ | | `exitscript` | `bool` | exit script if returning False | `False` | Returns: | Type | Description | | --- | --- | | `bool` | True if view is a graphical view | Examples: ```md-code__content from pyrevit import forms forms.check_graphicalview(revit.active_view) True ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
``` | ````md-code__content
def check_graphicalview(view, exitscript=False):
"""Verify target view is a graphical view.
Args:
view (DB.View): target view
exitscript (bool): exit script if returning False
Returns:
(bool): True if view is a graphical view
Examples:
```python
from pyrevit import forms
forms.check_graphicalview(revit.active_view)
True
```
"""
if not view.Category:
alert(
"Active view must be a grahical view.",
exitscript=exitscript
)
return False
return True
```` | ### `toast(message, title='pyRevit', appid='pyRevit', icon=None, click=None, actions=None)` Show a Windows 10 notification. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | notification message | _required_ | | `title` | `str` | notification title | `'pyRevit'` | | `appid` | `str` | app name (will show under message) | `'pyRevit'` | | `icon` | `str` | file path to icon .ico file (defaults to pyRevit icon) | `None` | | `click` | `str` | click action commands string | `None` | | `actions` | `dict` | dictionary of button names and action strings | `None` | Examples: ```md-code__content script.toast("Hello World!", title="My Script", appid="MyAPP", click="https://pyrevitlabs.github.io/pyRevit/", actions={ "Open Google":"https://google.com", "Open Toast64":"https://github.com/go-toast/toast" }) ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
``` | ````md-code__content
def toast(message, title='pyRevit', appid='pyRevit',
icon=None, click=None, actions=None):
"""Show a Windows 10 notification.
Args:
message (str): notification message
title (str): notification title
appid (str): app name (will show under message)
icon (str): file path to icon .ico file (defaults to pyRevit icon)
click (str): click action commands string
actions (dict): dictionary of button names and action strings
Examples:
```python
script.toast("Hello World!",
title="My Script",
appid="MyAPP",
click="https://pyrevitlabs.github.io/pyRevit/",
actions={
"Open Google":"https://google.com",
"Open Toast64":"https://github.com/go-toast/toast"
})
```
"""
toaster.send_toast(
message,
title=title,
appid=appid,
icon=icon,
click=click,
actions=actions)
```` | ### `ask_for_string(default=None, prompt=None, title=None, **kwargs)` Ask user to select a string value. This is a shortcut function that configures :obj: `GetValueWindow` for string data types. kwargs can be used to pass on other arguments. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `default` | `str` | default unique string. must not be in reserved\_values | `None` | | `prompt` | `str` | prompt message | `None` | | `title` | `str` | title message | `None` | | `kwargs` | `type` | other arguments to be passed to :obj: `GetValueWindow` | `{}` | Returns: | Type | Description | | --- | --- | | `str` | selected string value | Examples: ```md-code__content forms.ask_for_string( default='some-tag', prompt='Enter new tag name:', title='Tag Manager') 'new-tag' ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
``` | ````md-code__content
def ask_for_string(default=None, prompt=None, title=None, **kwargs):
"""Ask user to select a string value.
This is a shortcut function that configures :obj:`GetValueWindow` for
string data types. kwargs can be used to pass on other arguments.
Args:
default (str): default unique string. must not be in reserved_values
prompt (str): prompt message
title (str): title message
kwargs (type): other arguments to be passed to :obj:`GetValueWindow`
Returns:
(str): selected string value
Examples:
```python
forms.ask_for_string(
default='some-tag',
prompt='Enter new tag name:',
title='Tag Manager')
'new-tag'
```
"""
return GetValueWindow.show(
None,
value_type='string',
default=default,
prompt=prompt,
title=title,
**kwargs
)
```` | ### `ask_for_unique_string(reserved_values, default=None, prompt=None, title=None, **kwargs)` Ask user to select a unique string value. This is a shortcut function that configures :obj: `GetValueWindow` for unique string data types. kwargs can be used to pass on other arguments. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `reserved_values` | `list[str]` | list of reserved (forbidden) values | _required_ | | `default` | `str` | default unique string. must not be in reserved\_values | `None` | | `prompt` | `str` | prompt message | `None` | | `title` | `str` | title message | `None` | | `kwargs` | `type` | other arguments to be passed to :obj: `GetValueWindow` | `{}` | Returns: | Type | Description | | --- | --- | | `str` | selected unique string | Examples: ```md-code__content forms.ask_for_unique_string( prompt='Enter a Unique Name', title=self.Title, reserved_values=['Ehsan', 'Gui', 'Guido'], owner=self) 'unique string' ``` In example above, owner argument is provided to be passed to underlying :obj: `GetValueWindow`. Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
``` | ````md-code__content
def ask_for_unique_string(reserved_values,
default=None, prompt=None, title=None, **kwargs):
"""Ask user to select a unique string value.
This is a shortcut function that configures :obj:`GetValueWindow` for
unique string data types. kwargs can be used to pass on other arguments.
Args:
reserved_values (list[str]): list of reserved (forbidden) values
default (str): default unique string. must not be in reserved_values
prompt (str): prompt message
title (str): title message
kwargs (type): other arguments to be passed to :obj:`GetValueWindow`
Returns:
(str): selected unique string
Examples:
```python
forms.ask_for_unique_string(
prompt='Enter a Unique Name',
title=self.Title,
reserved_values=['Ehsan', 'Gui', 'Guido'],
owner=self)
'unique string'
```
In example above, owner argument is provided to be passed to underlying
:obj:`GetValueWindow`.
"""
return GetValueWindow.show(
None,
value_type='string',
default=default,
prompt=prompt,
title=title,
reserved_values=reserved_values,
**kwargs
)
```` | ### `ask_for_one_item(items, default=None, prompt=None, title=None, **kwargs)` Ask user to select an item from a list of items. This is a shortcut function that configures :obj: `GetValueWindow` for 'single-select' data types. kwargs can be used to pass on other arguments. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `items` | `list[str]` | list of items to choose from | _required_ | | `default` | `str` | default selected item | `None` | | `prompt` | `str` | prompt message | `None` | | `title` | `str` | title message | `None` | | `kwargs` | `type` | other arguments to be passed to :obj: `GetValueWindow` | `{}` | Returns: | Type | Description | | --- | --- | | `str` | selected item | Examples: ```md-code__content forms.ask_for_one_item( ['test item 1', 'test item 2', 'test item 3'], default='test item 2', prompt='test prompt', title='test title' ) 'test item 1' ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
``` | ````md-code__content
def ask_for_one_item(items, default=None, prompt=None, title=None, **kwargs):
"""Ask user to select an item from a list of items.
This is a shortcut function that configures :obj:`GetValueWindow` for
'single-select' data types. kwargs can be used to pass on other arguments.
Args:
items (list[str]): list of items to choose from
default (str): default selected item
prompt (str): prompt message
title (str): title message
kwargs (type): other arguments to be passed to :obj:`GetValueWindow`
Returns:
(str): selected item
Examples:
```python
forms.ask_for_one_item(
['test item 1', 'test item 2', 'test item 3'],
default='test item 2',
prompt='test prompt',
title='test title'
)
'test item 1'
```
"""
return GetValueWindow.show(
items,
value_type='dropdown',
default=default,
prompt=prompt,
title=title,
**kwargs
)
```` | ### `ask_for_date(default=None, prompt=None, title=None, **kwargs)` Ask user to select a date value. This is a shortcut function that configures :obj: `GetValueWindow` for date data types. kwargs can be used to pass on other arguments. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `default` | `datetime` | default selected date value | `None` | | `prompt` | `str` | prompt message | `None` | | `title` | `str` | title message | `None` | | `kwargs` | `type` | other arguments to be passed to :obj: `GetValueWindow` | `{}` | Returns: | Type | Description | | --- | --- | | `datetime` | selected date | Examples: ```md-code__content forms.ask_for_date(default="", title="Enter deadline:") datetime.datetime(2019, 5, 17, 0, 0) ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
``` | ````md-code__content
def ask_for_date(default=None, prompt=None, title=None, **kwargs):
"""Ask user to select a date value.
This is a shortcut function that configures :obj:`GetValueWindow` for
date data types. kwargs can be used to pass on other arguments.
Args:
default (datetime.datetime): default selected date value
prompt (str): prompt message
title (str): title message
kwargs (type): other arguments to be passed to :obj:`GetValueWindow`
Returns:
(datetime.datetime): selected date
Examples:
```python
forms.ask_for_date(default="", title="Enter deadline:")
datetime.datetime(2019, 5, 17, 0, 0)
```
"""
# FIXME: window does not set default value
return GetValueWindow.show(
None,
value_type='date',
default=default,
prompt=prompt,
title=title,
**kwargs
)
```` | ### `ask_for_number_slider(default=None, min=0, max=100, interval=1, prompt=None, title=None, **kwargs)` Ask user to select a number value. This is a shortcut function that configures :obj: `GetValueWindow` for numbers. kwargs can be used to pass on other arguments. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `default` | `str` | default unique string. must not be in reserved\_values | `None` | | `min` | `int` | minimum value on slider | `0` | | `max` | `int` | maximum value on slider | `100` | | `interval` | `int` | number interval between values | `1` | | `prompt` | `str` | prompt message | `None` | | `title` | `str` | title message | `None` | | `kwargs` | `type` | other arguments to be passed to :obj: `GetValueWindow` | `{}` | Returns: | Type | Description | | --- | --- | | `str` | selected string value | Examples: ```md-code__content forms.ask_for_number_slider( default=50, min = 0, max = 100, interval = 5, prompt='Select a number:', title='test title') '50' ``` In this example, the slider will allow values such as '40, 45, 50, 55, 60' etc Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
``` | ````md-code__content
def ask_for_number_slider(default=None, min=0, max=100, interval=1, prompt=None, title=None, **kwargs):
"""Ask user to select a number value.
This is a shortcut function that configures :obj:`GetValueWindow` for
numbers. kwargs can be used to pass on other arguments.
Args:
default (str): default unique string. must not be in reserved_values
min (int): minimum value on slider
max (int): maximum value on slider
interval (int): number interval between values
prompt (str): prompt message
title (str): title message
kwargs (type): other arguments to be passed to :obj:`GetValueWindow`
Returns:
(str): selected string value
Examples:
```python
forms.ask_for_number_slider(
default=50,
min = 0,
max = 100,
interval = 5,
prompt='Select a number:',
title='test title')
'50'
```
In this example, the slider will allow values such as '40, 45, 50, 55, 60' etc
"""
return GetValueWindow.show(
None,
value_type='slider',
default=default,
prompt=prompt,
title=title,
max=max,
min=min,
interval=interval,
**kwargs
)
```` | ### `ask_to_use_selected(type_name, count=None, multiple=True)` Ask user if wants to use currently selected elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `type_name` | `str` | Element type of expected selected elements | _required_ | | `count` | `int` | Number of selected items | `None` | | `multiple` | `bool` | Whether multiple selected items are allowed | `True` | Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
``` | ```md-code__content
def ask_to_use_selected(type_name, count=None, multiple=True):
"""Ask user if wants to use currently selected elements.
Args:
type_name (str): Element type of expected selected elements
count (int): Number of selected items
multiple (bool): Whether multiple selected items are allowed
"""
report = type_name.lower()
# multiple = True
message = \
"You currently have %s selected. Do you want to proceed with "\
"currently selected item(s)?"
# check is selecting multiple is allowd
if not multiple:
# multiple = False
message = \
"You currently have %s selected and only one is required. "\
"Do you want to use the first selected item?"
# check if count is provided
if count is not None:
report = '{} {}'.format(count, report)
return alert(message % report, yes=True, no=True)
``` | ### `ask_for_color(default=None)` Show system color picker and ask for color. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `default` | `str` | default color in HEX ARGB e.g. #ff808080 | `None` | Returns: | Type | Description | | --- | --- | | `str` | selected color in HEX ARGB e.g. #ff808080, or None if cancelled | Examples: ```md-code__content forms.ask_for_color() '#ff808080' ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
``` | ````md-code__content
def ask_for_color(default=None):
"""Show system color picker and ask for color.
Args:
default (str): default color in HEX ARGB e.g. #ff808080
Returns:
(str): selected color in HEX ARGB e.g. #ff808080, or None if cancelled
Examples:
```python
forms.ask_for_color()
'#ff808080'
```
"""
# colorDlg.Color
color_picker = Forms.ColorDialog()
if default:
default = default.replace('#', '')
color_picker.Color = System.Drawing.Color.FromArgb(
int(default[:2], 16),
int(default[2:4], 16),
int(default[4:6], 16),
int(default[6:8], 16)
)
color_picker.FullOpen = True
if color_picker.ShowDialog() == Forms.DialogResult.OK:
c = color_picker.Color
c_hex = ''.join('{:02X}'.format(int(x)) for x in [c.A, c.R, c.G, c.B])
return '#' + c_hex
```` | ### `inform_wip()` Show work-in-progress prompt to user and exit script. Examples: ```md-code__content forms.inform_wip() ``` Source code in `pyrevitlib/pyrevit/forms/__init__.py` | | | | --- | --- | | ```
3618
3619
3620
3621
3622
3623
3624
3625
3626
``` | ````md-code__content
def inform_wip():
"""Show work-in-progress prompt to user and exit script.
Examples:
```python
forms.inform_wip()
```
"""
alert("Work in progress.", exitscript=True)
```` | Back to top ## pyRevit Unit Tests [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/unittests/#pyrevit.unittests) # unittests The main pyRevit test is the startup test which is done by launching Revit. This module is created to provide a platform to perform complete tests on different components of pyRevit. For example, as the git module grows, new tests will be added to the git test suite to test the full functionality of that module, although only a subset of functions are used during startup and normal operations of pyRevit. ```md-code__content from unittest import TestCase class TestWithIndependentOutput(TestCase): def setUp(self): pass def tearDown(self): pass def doCleanups(self): pass ``` ## Functions Back to top ## Locale Conversion Services [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/applocales/#pyrevit.coreutils.applocales) # applocales Provide conversion services between python.locale and host languages. ## Attributes ### `DEFAULT_LANG_DIR = 'LTR'``module-attribute` ### `DEFAULT_LOCALE = AppLocale(lang_type=ApplicationServices.LanguageType.English_USA, lang_name='English USA', locale_codes=['en_us', 'english'])``module-attribute` ### `APP_LOCALES = [DEFAULT_LOCALE, AppLocale(lang_type=ApplicationServices.LanguageType.German, lang_name='Deutsch', locale_codes=['de_de', 'german']), AppLocale(lang_type=ApplicationServices.LanguageType.Spanish, lang_name='español', locale_codes=['es_es', 'spanish']), AppLocale(lang_type=ApplicationServices.LanguageType.French, lang_name='français', locale_codes=['fr_fr', 'french']), AppLocale(lang_type=ApplicationServices.LanguageType.Italian, lang_name='italiano', locale_codes=['it_it', 'italian']), AppLocale(lang_type=ApplicationServices.LanguageType.Dutch, lang_name='Nederlands', locale_codes=['nl_nl', 'nl_be', 'dutch']), AppLocale(lang_type=ApplicationServices.LanguageType.Chinese_Simplified, lang_name='简体中文', locale_codes=['chinese_s', 'chinese']), AppLocale(lang_type=ApplicationServices.LanguageType.Chinese_Traditional, lang_name='繁體中文', locale_codes=['chinese_t', 'chinese']), AppLocale(lang_type=ApplicationServices.LanguageType.Japanese, lang_name='日本語', locale_codes=['ja', 'japanese']), AppLocale(lang_type=ApplicationServices.LanguageType.Korean, lang_name='한국어', locale_codes=['ko', 'korean']), AppLocale(lang_type=ApplicationServices.LanguageType.Russian, lang_name='Русский', locale_codes=['ru', 'russian']), AppLocale(lang_type=ApplicationServices.LanguageType.Czech, lang_name='Čeština', locale_codes=['cs', 'czech']), AppLocale(lang_type=ApplicationServices.LanguageType.Polish, lang_name='Polski', locale_codes=['pl', 'polish']), AppLocale(lang_type=ApplicationServices.LanguageType.Hungarian, lang_name='Magyar', locale_codes=['hu', 'hungarian']), AppLocale(lang_type=ApplicationServices.LanguageType.Brazilian_Portuguese, lang_name='Português do Brasil', locale_codes=['pt_br', 'portuguese_brazil', 'brazilian', 'portuguese', 'pt_pt'])]``module-attribute` ## Classes ### `AppLocale(lang_type, locale_codes, lang_name=None, lang_dir=DEFAULT_LANG_DIR)` Bases: `object` Type representing a language option. Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
14
15
16
17
18
19
20
21
22
23
24
25
26
27
``` | ```md-code__content
def __init__(self,
lang_type,
locale_codes,
lang_name=None,
lang_dir=DEFAULT_LANG_DIR):
if isinstance(lang_type, ApplicationServices.LanguageType):
self.lang_type = lang_type
elif isinstance(lang_type, str):
self.lang_type = lang_type
self.lang_name = lang_name
self.lang_dir = lang_dir
self.locale_codes = locale_codes
if self.locale_codes:
self.locale_code = self.locale_codes[0]
``` | #### Attributes ##### `lang_type = lang_type``instance-attribute` ##### `lang_name = lang_name``instance-attribute` ##### `lang_dir = lang_dir``instance-attribute` ##### `locale_codes = locale_codes``instance-attribute` ##### `locale_code = self.locale_codes[0]``instance-attribute` ## Functions ### `get_applocale_by_local_code(locale_code)` Return application locale by locale code. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `locale_code` | `str` | locale code | _required_ | Returns: | Type | Description | | --- | --- | | `AppLocale` | application locale | Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
146
147
148
149
150
151
152
153
154
155
156
157
``` | ```md-code__content
def get_applocale_by_local_code(locale_code):
"""Return application locale by locale code.
Args:
locale_code (str): locale code
Returns:
(AppLocale): application locale
"""
for applocale in APP_LOCALES:
if locale_code in applocale.locale_codes:
return applocale
``` | ### `get_applocale_by_lang_type(lang_type)` Return application locale by language type. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `lang_type` | `LanguageType | str` | language type | _required_ | Returns: | Type | Description | | --- | --- | | `AppLocale` | application locale | Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
160
161
162
163
164
165
166
167
168
169
170
171
``` | ```md-code__content
def get_applocale_by_lang_type(lang_type):
"""Return application locale by language type.
Args:
lang_type (ApplicationServices.LanguageType | str): language type
Returns:
(AppLocale): application locale
"""
for applocale in APP_LOCALES:
if lang_type == applocale.lang_type:
return applocale
``` | ### `get_applocale_by_lang_name(lang_name)` Return application locale by language name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `lang_name` | `str` | language name | _required_ | Returns: | Type | Description | | --- | --- | | `AppLocale` | application locale | Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
174
175
176
177
178
179
180
181
182
183
184
185
``` | ```md-code__content
def get_applocale_by_lang_name(lang_name):
"""Return application locale by language name.
Args:
lang_name (str): language name
Returns:
(AppLocale): application locale
"""
for applocale in APP_LOCALES:
if lang_name in {applocale.lang_name, str(applocale.lang_type)}:
return applocale
``` | ### `get_current_applocale()` Return the current locale. This is the user locale, if set, or the host application locale otherwise. Returns: | Type | Description | | --- | --- | | `AppLocale` | current locale | Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
188
189
190
191
192
193
194
195
196
197
198
``` | ```md-code__content
def get_current_applocale():
"""Return the current locale.
This is the user locale, if set, or the host application locale otherwise.
Returns:
(AppLocale): current locale
"""
if user_config.user_locale:
return get_applocale_by_local_code(user_config.user_locale)
return get_applocale_by_lang_type(HOST_APP.language)
``` | ### `get_host_applocale()` Return host application locale. Returns: | Type | Description | | --- | --- | | `AppLocale` | host application locale | Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
201
202
203
204
205
206
207
``` | ```md-code__content
def get_host_applocale():
"""Return host application locale.
Returns:
(AppLocale): host application locale
"""
return get_applocale_by_lang_type(HOST_APP.language)
``` | ### `get_locale_string(string_dict)` Returns the correct string from given dict based on host language. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `string_dict` | `dict[str, str]` | dict of strings in various locales | _required_ | Returns: | Type | Description | | --- | --- | | `str` | string in correct locale | Examples: ```md-code__content data = {"en_us":"Hello", "chinese_s":"你好"} from pyrevit.coreutils import applocales # assuming running Revit is Chinese applocales.get_locale_string(data) ``` "你好" Source code in `pyrevitlib/pyrevit/coreutils/applocales.py` | | | | --- | --- | | ```
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
``` | ````md-code__content
def get_locale_string(string_dict):
"""Returns the correct string from given dict based on host language.
Args:
string_dict (dict[str, str]): dict of strings in various locales
Returns:
(str): string in correct locale
Examples:
```python
data = {"en_us":"Hello", "chinese_s":"你好"}
from pyrevit.coreutils import applocales
# assuming running Revit is Chinese
applocales.get_locale_string(data)
```
"你好"
"""
applocale = get_applocale_by_local_code(user_config.user_locale)
if applocale:
local_codes = applocale.locale_codes + DEFAULT_LOCALE.locale_codes
else:
local_codes = DEFAULT_LOCALE.locale_codes
for locale_code in local_codes:
if locale_code in string_dict:
return string_dict[locale_code]
```` | Back to top ## Event Telemetry Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/telemetry/events/#pyrevit.telemetry.events) # events Event telemetry management. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `ALL_EVENTS = 340282366920938463463374607431768211455``module-attribute` ### `SUGGESTED_EVENTS = 31988513242969``module-attribute` ## Functions ### `register_event_telemetry(handler, flags)` Registers application event telemetry handlers based on given flags. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `handler` | `EventTelemetry` | event telemetry handler | _required_ | | `flags` | `int` | event flags | _required_ | Source code in `pyrevitlib/pyrevit/telemetry/events.py` | | | | --- | --- | | ```
21
22
23
24
25
26
27
28
29
30
31
32
33
``` | ```md-code__content
def register_event_telemetry(handler, flags):
"""Registers application event telemetry handlers based on given flags.
Args:
handler (EventTelemetry): event telemetry handler
flags (int): event flags
"""
try:
handler.RegisterEventTelemetry(HOST_APP.uiapp, flags)
except Exception as ex:
mlogger.debug(
"Error registering event telementry with flags: %s | %s",
str(flags), ex)
``` | ### `unregister_event_telemetry(handler, flags)` Unregisters application event telemetry handlers based on given flags. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `handler` | `EventTelemetry` | event telemetry handler | _required_ | | `flags` | `int` | event flags | _required_ | Source code in `pyrevitlib/pyrevit/telemetry/events.py` | | | | --- | --- | | ```
36
37
38
39
40
41
42
43
44
45
46
47
48
``` | ```md-code__content
def unregister_event_telemetry(handler, flags):
"""Unregisters application event telemetry handlers based on given flags.
Args:
handler (EventTelemetry): event telemetry handler
flags (int): event flags
"""
try:
handler.UnRegisterEventTelemetry(HOST_APP.uiapp, flags)
except Exception as ex:
mlogger.debug(
"Error unregistering event telementry with flags: %s | %s",
str(flags), ex)
``` | ### `unregister_all_event_telemetries(handler)` Unregisters all available application event telemetry handlers. Source code in `pyrevitlib/pyrevit/telemetry/events.py` | | | | --- | --- | | ```
51
52
53
``` | ```md-code__content
def unregister_all_event_telemetries(handler):
"""Unregisters all available application event telemetry handlers."""
unregister_event_telemetry(handler, ALL_EVENTS)
``` | Back to top ## Revit Journal Files [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/journals/#pyrevit.revit.journals) # journals Provide access to Revit Journal Files. ## Attributes ## Functions ### `get_journals_folder()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
12
13
``` | ```md-code__content
def get_journals_folder():
return op.dirname(HOST_APP.app.RecordingJournalFilename)
``` | ### `get_current_journal_file()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
16
17
``` | ```md-code__content
def get_current_journal_file():
return HOST_APP.app.RecordingJournalFilename
``` | ### `get_current_session_id()` Source code in `pyrevitlib/pyrevit/revit/journals.py` | | | | --- | --- | | ```
20
21
22
23
24
25
26
27
``` | ```md-code__content
def get_current_session_id():
re_finder = re.compile(r'.*>Session\s+(\$.{8}).*')
journal_file = get_current_journal_file()
with open(journal_file, "r") as jfile:
for jline in reversed(jfile.readlines()):
match = re_finder.match(jline)
if match:
return match.groups()[0]
``` | Back to top ## ASCII Caching Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/cacher_asc/#pyrevit.extensions.cacher_asc) # cacher\_asc Base module to handle extension ASCII caching. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Classes ## Functions ### `update_cache(parsed_ext)` Source code in `pyrevitlib/pyrevit/extensions/cacher_asc.py` | | | | --- | --- | | ```
120
121
122
123
``` | ```md-code__content
def update_cache(parsed_ext):
mlogger.debug('Updating cache for tab: %s ...', parsed_ext.name)
_write_cache_for(parsed_ext)
mlogger.debug('Cache updated for tab: %s', parsed_ext.name)
``` | ### `get_cached_extension(installed_ext)` Source code in `pyrevitlib/pyrevit/extensions/cacher_asc.py` | | | | --- | --- | | ```
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
``` | ```md-code__content
def get_cached_extension(installed_ext):
cached_ext_dict = _read_cache_for(installed_ext)
# try:
mlogger.debug('Constructing components from cache for: %s',
installed_ext)
# get cached sub component dictionary and call recursive maker function
_make_sub_cmp_from_cache(installed_ext,
cached_ext_dict.pop(gencomps.SUB_CMP_KEY))
mlogger.debug('Load successful...')
# except Exception as err:
# mlogger.debug('Error reading cache...')
# raise PyRevitException('Error creating ext from cache for: {} | {}'
# .format(installed_ext.name, err))
return installed_ext
``` | ### `is_cache_valid(extension)` Source code in `pyrevitlib/pyrevit/extensions/cacher_asc.py` | | | | --- | --- | | ```
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
``` | ```md-code__content
def is_cache_valid(extension):
try:
cached_ext_dict = _read_cache_for(extension) # type: dict
mlogger.debug('Extension cache directory is: %s for: %s',
extension.directory, extension)
cache_dir_valid = cached_ext_dict[gencomps.EXT_DIR_KEY] == extension.directory
mlogger.debug('Extension cache version is: %s for: %s',
extension.pyrvt_version, extension)
cache_version_valid = \
cached_ext_dict[comps.EXT_HASH_VERSION_KEY] == extension.pyrvt_version
mlogger.debug('Extension hash value is: %s for:%s',
extension.dir_hash_value, extension)
cache_hash_valid = \
cached_ext_dict[comps.EXT_HASH_VALUE_KEY] == extension.dir_hash_value
cache_valid = \
cache_dir_valid and cache_version_valid and cache_hash_valid
# cache is valid if both version and hash value match
return cache_valid
except PyRevitException as err:
mlogger.debug(err)
return False
except Exception as err:
mlogger.debug('Error determining cache validity: %s | %s',
extension, err)
``` | Back to top ## pyRevit Environment Variables [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/envvars/#pyrevit.coreutils.envvars) # envvars pyRevit managed environment variables framework. pyRevit provides the environment variables framework to the pyRevit core and all pyRevit tools so they can store arbitary data withing the running host session and share small data quickly between script runs. Some settings needs to be set for the current session and might need to affect the behaviour of all individual scripts inside the extensions. (e.g. If user activates the `DEBUG` mode, all scripts should follow and log the debug entries.) The information is saved using `AppDomain.GetData` and `SetData` in a dictionary parameter. The dictionary is used to minimize the addition of named parameters to the AppDomain. The dictionary then includes all the internal parameters and their associated value. This way each script does not need to read the usersettings data which reduces io and saves time. pyRevit uses environment variables extensively at its core and making changes to the core environment variables (starting with `PYREVIT_`) through scripts is strongly prohibited. Examples: ```md-code__content from pyrevit.coreutils import envvars envvars.set_pyrevit_env_var('MY_SCRIPT_STATUS', True) envvars.set_pyrevit_env_var('MY_SCRIPT_CONFIG', {'someconfig': True}) ``` Then another script or same script when executed later within the same session can query the shared environment variable: ```md-code__content envvars.get_pyrevit_env_vars('MY_SCRIPT_STATUS') ``` True ```md-code__content envvars.get_pyrevit_env_vars('MY_SCRIPT_CONFIG') ``` {'someconfig': True} ## Attributes ### `PRODUCT_NAME = str(Common.PyRevitLabsConsts.ProductName).upper()``module-attribute` ### `ENV_VAR_DICT_NAME = PRODUCT_NAME + 'EnvVarsDict'``module-attribute` ### `SESSIONUUID_ENVVAR = PRODUCT_NAME + '_UUID'``module-attribute` ### `APPVERSION_ENVVAR = PRODUCT_NAME + '_APPVERSION'``module-attribute` ### `VERSION_ENVVAR = PRODUCT_NAME + '_VERSION'``module-attribute` ### `CLONENAME_ENVVAR = PRODUCT_NAME + '_CLONE'``module-attribute` ### `IPYVERSION_ENVVAR = PRODUCT_NAME + '_IPYVERSION'``module-attribute` ### `CPYVERSION_ENVVAR = PRODUCT_NAME + '_CPYVERSION'``module-attribute` ### `LOGGING_LEVEL_ENVVAR = PRODUCT_NAME + '_LOGGINGLEVEL'``module-attribute` ### `FILELOGGING_ENVVAR = PRODUCT_NAME + '_FILELOGGING'``module-attribute` ### `LOADEDASSMS_ENVVAR = PRODUCT_NAME + '_LOADEDASSMS'``module-attribute` ### `REFEDASSMS_ENVVAR = PRODUCT_NAME + '_REFEDASSMS'``module-attribute` ### `TELEMETRYSTATE_ENVVAR = PRODUCT_NAME + '_TELEMETRYSTATE'``module-attribute` ### `TELEMETRYUTCTIMESTAMPS_ENVVAR = PRODUCT_NAME + '_TELEMETRYUTCTIMESTAMPS'``module-attribute` ### `TELEMETRYDIR_ENVVAR = PRODUCT_NAME + '_TELEMETRYDIR'``module-attribute` ### `TELEMETRYFILE_ENVVAR = PRODUCT_NAME + '_TELEMETRYFILE'``module-attribute` ### `TELEMETRYSERVER_ENVVAR = PRODUCT_NAME + '_TELEMETRYSERVER'``module-attribute` ### `TELEMETRYINCLUDEHOOKS_ENVVAR = PRODUCT_NAME + '_TELEMETRYINCLUDEHOOKS'``module-attribute` ### `APPTELEMETRYSTATE_ENVVAR = PRODUCT_NAME + '_APPTELEMETRYSTATE'``module-attribute` ### `APPTELEMETRYHANDLER_ENVVAR = PRODUCT_NAME + '_APPTELEMETRYHANDLER'``module-attribute` ### `APPTELEMETRYSERVER_ENVVAR = PRODUCT_NAME + '_APPTELEMETRYSERVER'``module-attribute` ### `APPTELEMETRYEVENTFLAGS_ENVVAR = PRODUCT_NAME + '_APPTELEMETRYEVENTFLAGS'``module-attribute` ### `ROUTES_SERVER = PRODUCT_NAME + '_ROUTESSERVER'``module-attribute` ### `ROUTES_ROUTES = PRODUCT_NAME + '_ROUTESROUTES'``module-attribute` ### `HOOKS_ENVVAR = PRODUCT_NAME + '_HOOKS'``module-attribute` ### `HOOKSHANDLER_ENVVAR = PRODUCT_NAME + '_HOOKSHANDLER'``module-attribute` ### `AUTOUPDATING_ENVVAR = PRODUCT_NAME + '_AUTOUPDATE'``module-attribute` ### `OUTPUT_STYLESHEET_ENVVAR = PRODUCT_NAME + '_STYLESHEET'``module-attribute` ### `RIBBONUPDATOR_ENVVAR = PRODUCT_NAME + '_RIBBONUPDATOR'``module-attribute` ### `TABCOLORIZER_ENVVAR = PRODUCT_NAME + '_TABCOLORIZER'``module-attribute` ## Functions ### `get_pyrevit_env_vars()` Get the root dictionary, holding all environment variables. Source code in `pyrevitlib/pyrevit/coreutils/envvars.py` | | | | --- | --- | | ```
89
90
91
``` | ```md-code__content
def get_pyrevit_env_vars():
"""Get the root dictionary, holding all environment variables."""
return AppDomain.CurrentDomain.GetData(ENV_VAR_DICT_NAME)
``` | ### `get_pyrevit_env_var(param_name)` Get value of a parameter shared between all scripts. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | name of environment variable | _required_ | Returns: | Type | Description | | --- | --- | | `object` | any object stored as the environment variable value | Source code in `pyrevitlib/pyrevit/coreutils/envvars.py` | | | | --- | --- | | ```
94
95
96
97
98
99
100
101
102
103
104
105
106
107
``` | ```md-code__content
def get_pyrevit_env_var(param_name):
"""Get value of a parameter shared between all scripts.
Args:
param_name (str): name of environment variable
Returns:
(object): any object stored as the environment variable value
"""
# This function returns None if it can not find the parameter.
# Thus value of None should not be used for params
data_dict = get_pyrevit_env_vars()
return data_dict.get(param_name) if data_dict else None
``` | ### `set_pyrevit_env_var(param_name, param_value)` Set value of a parameter shared between all scripts. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | name of environment variable | _required_ | | `param_value` | `object` | any python object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/envvars.py` | | | | --- | --- | | ```
110
111
112
113
114
115
116
117
118
119
120
121
``` | ```md-code__content
def set_pyrevit_env_var(param_name, param_value):
"""Set value of a parameter shared between all scripts.
Args:
param_name (str): name of environment variable
param_value (object): any python object
"""
# Get function returns None if it can not find the parameter.
# Thus value of None should not be used for params
data_dict = get_pyrevit_env_vars() or {}
data_dict[param_name] = param_value
AppDomain.CurrentDomain.SetData(ENV_VAR_DICT_NAME, data_dict)
``` | Back to top ## Extension Package Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/extpackages/#pyrevit.extensions.extpackages) # extpackages Base module to handle processing extensions as packages. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `PLUGIN_EXT_DEF_MANIFEST_NAME = 'extensions'``module-attribute` ### `PLUGIN_EXT_DEF_FILE = PLUGIN_EXT_DEF_MANIFEST_NAME + exts.JSON_FILE_FORMAT``module-attribute` ### `EXTENSION_POSTFIXES = [x.POSTFIX for x in exts.ExtensionTypes.get_ext_types()]``module-attribute` ## Classes ### `PyRevitPluginAlreadyInstalledException(extpkg)` Bases: `PyRevitException` Exception raised when extension is already installed. Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
24
25
26
27
``` | ```md-code__content
def __init__(self, extpkg):
super(PyRevitPluginAlreadyInstalledException, self).__init__()
self.extpkg = extpkg
PyRevitException(self)
``` | #### Attributes ##### `msg``property` Return exception message. ##### `extpkg = extpkg``instance-attribute` ### `PyRevitPluginNoInstallLinkException` Bases: `PyRevitException` Exception raised when extension does not have an install link. #### Attributes ##### `msg``property` Return exception message. ### `PyRevitPluginRemoveException` Bases: `PyRevitException` Exception raised when removing an extension. #### Attributes ##### `msg``property` Return exception message. ### `DependencyGraph(extpkg_list)` Extension packages dependency graph. Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
48
49
50
51
52
53
54
``` | ```md-code__content
def __init__(self, extpkg_list):
self.dep_dict = defaultdict(list)
self.extpkgs = extpkg_list
for extpkg in extpkg_list:
if extpkg.dependencies:
for dep_pkg_name in extpkg.dependencies:
self.dep_dict[dep_pkg_name].append(extpkg)
``` | #### Attributes ##### `dep_dict = defaultdict(list)``instance-attribute` ##### `extpkgs = extpkg_list``instance-attribute` #### Functions ##### `has_installed_dependents(extpkg_name)` Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
56
57
58
59
60
61
62
``` | ```md-code__content
def has_installed_dependents(self, extpkg_name):
if extpkg_name in self.dep_dict:
for dep_pkg in self.dep_dict[extpkg_name]:
if dep_pkg.is_installed:
return True
else:
return False
``` | ### `ExtensionPackage(info_dict, def_file_path=None)` Extension package class. This class contains the extension information and also manages installation, user configuration, and removal of the extension. See the `__init__` class documentation for the required and optional extension information. Attributes: | Name | Type | Description | | --- | --- | --- | | `type` | `ExtensionTypes` | Extension type | | `name` | `str` | Extension name | | `description` | `str` | Extension description | | `url` | `str` | Url of online git repository | | `website` | `str` | Url of extension website | | `image` | `str` | Url of extension icon image (.png file) | | `author` | `str` | Name of extension author | | `author_profile` | `str` | Url of author profile | Initialized the extension class based on provide information. Required info (Dictionary keys): type, name, description, url Optional info website, image, author, author-url, authusers Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `info_dict` | `dict` | A dictionary containing the required information
for initializing the extension. | _required_ | | `def_file_path` | `str` | The file path of the extension definition file | `None` | Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
``` | ```md-code__content
def __init__(self, info_dict, def_file_path=None):
"""Initialized the extension class based on provide information.
Required info (Dictionary keys):
type, name, description, url
Optional info:
website, image, author, author-url, authusers
Args:
info_dict (dict): A dictionary containing the required information
for initializing the extension.
def_file_path (str): The file path of the extension definition file
"""
self.type = exts.ExtensionTypes.UI_EXTENSION
self.builtin = False
self.default_enabled = True
self.name = None
self.description = None
self.url = None
self.def_file_path = set()
self.authusers = set()
self.authgroups = set()
self.rocket_mode_compatible = False
self.website = None
self.image = None
self.author = None
self.author_profile = None
self.dependencies = set()
self.update_info(info_dict, def_file_path=def_file_path)
``` | #### Attributes ##### `type = exts.ExtensionTypes.UI_EXTENSION``instance-attribute` ##### `builtin = False``instance-attribute` ##### `default_enabled = True``instance-attribute` ##### `name = None``instance-attribute` ##### `description = None``instance-attribute` ##### `url = None``instance-attribute` ##### `def_file_path = set()``instance-attribute` ##### `authusers = set()``instance-attribute` ##### `authgroups = set()``instance-attribute` ##### `rocket_mode_compatible = False``instance-attribute` ##### `website = None``instance-attribute` ##### `image = None``instance-attribute` ##### `author = None``instance-attribute` ##### `author_profile = None``instance-attribute` ##### `dependencies = set()``instance-attribute` ##### `ext_dirname``property` Installation directory name to use. Returns: | Type | Description | | --- | --- | | `str` | The name that should be used for the installation directory
(based on the extension type). | ##### `is_installed``property` Installation directory. Returns: | Type | Description | | --- | --- | | `str` | Installed directory path or empty string if not installed. | ##### `installed_dir``property` Installation directory. Returns: | Type | Description | | --- | --- | | `str` | Installed directory path or empty string if not installed. | ##### `is_removable``property` Whether the extension is safe to remove. Checks whether it is safe to remove this extension by confirming if a git url is provided for this extension for later re-install. Returns: | Type | Description | | --- | --- | | `bool` | True if removable, False if not | ##### `version``property` Extension version. Returns: | Type | Description | | --- | --- | | `str` | Last commit hash of the extension git repo. | ##### `config``property` Returns a valid config manager for this extension. All config parameters will be saved in user config file. Returns: | Type | Description | | --- | --- | | `PyRevitConfigSectionParser` | Config section handler | ##### `is_enabled``property` Checks the default and user configured load state of the extension. Returns: | Type | Description | | --- | --- | | `bool` | True if package should be loaded | ##### `user_has_access``property` Checks whether current user has access to this extension. Returns: | Type | Description | | --- | --- | | `bool` | True is current user has access | #### Functions ##### `update_info(info_dict, def_file_path=None)` Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
``` | ```md-code__content
def update_info(self, info_dict, def_file_path=None):
ext_def_type = info_dict.get('type', None)
for ext_type in exts.ExtensionTypes.get_ext_types():
if ext_def_type == ext_type.ID:
self.type = ext_type
self.builtin = \
safe_strtype(info_dict.get('builtin',
self.builtin)).lower() == 'true'
self.default_enabled = safe_strtype(
info_dict.get('default_enabled', self.default_enabled)
).lower() == 'true'
self.name = info_dict.get('name', self.name)
self.description = info_dict.get('description', self.description)
self.url = info_dict.get('url', self.url)
if def_file_path:
self.def_file_path.add(def_file_path)
# update list of authorized users
authusers = info_dict.get('authusers', [])
if authusers:
self.authusers.update(authusers)
# update list of authorized user groups
authgroups = info_dict.get('authgroups', [])
if authgroups:
self.authgroups.update(authgroups)
# rocket mode compatibility
self.rocket_mode_compatible = \
safe_strtype(
info_dict.get('rocket_mode_compatible',
self.rocket_mode_compatible)
).lower() == 'true'
# extended attributes
self.website = info_dict.get(
'website',
self.url.replace('.git', '') if self.url else self.website
)
self.image = info_dict.get('image', self.image)
self.author = info_dict.get('author', self.author)
self.author_profile = info_dict.get('author_profile',
self.author_profile)
# update list dependencies
depends = info_dict.get('dependencies', [])
if depends:
self.dependencies.update(depends)
``` | ##### `is_valid()` Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
169
170
``` | ```md-code__content
def is_valid(self):
return self.name is not None and self.url is not None
``` | ##### `remove_pkg_config()` Removes the installed extension configuration. Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def remove_pkg_config(self):
"""Removes the installed extension configuration."""
user_config.remove_section(self.ext_dirname)
user_config.save_changes()
``` | ##### `disable_package()` Disables package in pyRevit configuration. It won't be loaded in the next session. Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
``` | ```md-code__content
def disable_package(self):
"""Disables package in pyRevit configuration.
It won't be loaded in the next session.
"""
self.config.disabled = True
user_config.save_changes()
``` | ##### `toggle_package()` Disables/Enables package in pyRevit configuration. A disabled package won't be loaded in the next session. Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
299
300
301
302
303
304
305
``` | ```md-code__content
def toggle_package(self):
"""Disables/Enables package in pyRevit configuration.
A disabled package won't be loaded in the next session.
"""
self.config.disabled = not self.config.disabled
user_config.save_changes()
``` | ## Functions ### `get_ext_packages(authorized_only=True)` Returns the registered plugin extensions packages. Reads the list of registered plug-in extensions and returns a list of ExtensionPackage classes which contain information on the plug-in extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `authorized_only` | `bool` | Only return authorized extensions | `True` | Returns: | Type | Description | | --- | --- | | `list[ExtensionPackage]` | list of registered plugin extensions | Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
``` | ```md-code__content
def get_ext_packages(authorized_only=True):
"""Returns the registered plugin extensions packages.
Reads the list of registered plug-in extensions and returns a list of
ExtensionPackage classes which contain information on the plug-in extension.
Args:
authorized_only (bool): Only return authorized extensions
Returns:
(list[ExtensionPackage]): list of registered plugin extensions
"""
extpkgs = []
for ext_dir in user_config.get_ext_root_dirs():
# make a list of all availabe extension definition sources
# default is under the extensions directory that ships with pyrevit
extpkg_def_files = {op.join(ext_dir, PLUGIN_EXT_DEF_FILE)}
# add other sources added by the user (using the cli)
extpkg_def_files.update(user_config.get_ext_sources())
for extpkg_def_file in extpkg_def_files:
mlogger.debug('Looking for %s', extpkg_def_file)
# check for external ext def file
if op.exists(extpkg_def_file):
mlogger.debug('Found %s', extpkg_def_file)
_update_extpkgs(extpkg_def_file, extpkgs)
# check internals now
internal_extpkg_defs = _find_internal_extpkgs(ext_dir)
for int_def_file in internal_extpkg_defs:
_update_extpkgs(int_def_file, extpkgs)
if authorized_only:
return [x for x in extpkgs if x.user_has_access]
return extpkgs
``` | ### `get_ext_package_by_name(extpkg_name)` Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
439
440
441
442
443
``` | ```md-code__content
def get_ext_package_by_name(extpkg_name):
for extpkg in get_ext_packages(authorized_only=False):
if extpkg.name == extpkg_name:
return extpkg
return None
``` | ### `get_dependency_graph()` Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
446
447
``` | ```md-code__content
def get_dependency_graph():
return DependencyGraph(get_ext_packages(authorized_only=False))
``` | ### `install(extpkg, install_dir, install_dependencies=True)` Install the extension in the given parent directory. This method uses .installed\_dir property of extension object as installation directory name for this extension. This method also handles installation of extension dependencies. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extpkg` | `ExtensionPackage` | Extension package to be installed | _required_ | | `install_dir` | `str` | Parent directory to install extension in. | _required_ | | `install_dependencies` | `bool` | Install the dependencies as well | `True` | Raises: | Type | Description | | --- | --- | | `PyRevitException` | on install error with error message | Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
``` | ```md-code__content
def install(extpkg, install_dir, install_dependencies=True):
"""Install the extension in the given parent directory.
This method uses .installed_dir property of extension object
as installation directory name for this extension.
This method also handles installation of extension dependencies.
Args:
extpkg (ExtensionPackage): Extension package to be installed
install_dir (str): Parent directory to install extension in.
install_dependencies (bool): Install the dependencies as well
Raises:
PyRevitException: on install error with error message
"""
try:
_install_extpkg(extpkg, install_dir, install_dependencies)
except PyRevitPluginAlreadyInstalledException as already_installed_err:
mlogger.warning('%s extension is already installed under %s',
already_installed_err.extpkg.name,
already_installed_err.extpkg.is_installed)
except PyRevitPluginNoInstallLinkException:
mlogger.error('Extension does not have an install link '
'and can not be installed.')
``` | ### `remove(extpkg, remove_dependencies=True)` Removes the extension. Removes the extension from its installed directory and clears its configuration. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extpkg` | `ExtensionPackage` | Extension package to be removed | _required_ | | `remove_dependencies` | `bool` | Remove the dependencies as well | `True` | Raises: | Type | Description | | --- | --- | | `PyRevitException` | on remove error with error message | Source code in `pyrevitlib/pyrevit/extensions/extpackages.py` | | | | --- | --- | | ```
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
``` | ```md-code__content
def remove(extpkg, remove_dependencies=True):
"""Removes the extension.
Removes the extension from its installed directory
and clears its configuration.
Args:
extpkg (ExtensionPackage): Extension package to be removed
remove_dependencies (bool): Remove the dependencies as well
Raises:
PyRevitException: on remove error with error message
"""
try:
_remove_extpkg(extpkg, remove_dependencies)
except PyRevitPluginRemoveException as remove_err:
mlogger.error('Error removing extension: %s | %s',
extpkg.name, remove_err)
``` | Back to top ## Charts Engine Overview [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/charts/#pyrevit.coreutils.charts) # charts Charts engine for output window. ## Attributes ### `CHARTS_ENGINE = 'Chart.bundle.js'``module-attribute` ### `LINE_CHART = 'line'``module-attribute` ### `BAR_CHART = 'bar'``module-attribute` ### `RADAR_CHART = 'radar'``module-attribute` ### `POLAR_CHART = 'polarArea'``module-attribute` ### `PIE_CHART = 'pie'``module-attribute` ### `DOUGHNUT_CHART = 'doughnut'``module-attribute` ### `BUBBLE_CHART = 'bubble'``module-attribute` ### `CHARTS_JS_PATH = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/{version}/Chart.min.js'``module-attribute` ### `SCRIPT_TEMPLATE = "var ctx = document.getElementById('{canvas_id}').getContext('2d');var chart = new Chart(ctx, {canvas_code});"``module-attribute` ## Classes ### `PyRevitOutputChartOptions()` Bases: `object` Chart options wrapper object. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
42
43
``` | ```md-code__content
def __init__(self):
pass
``` | ### `PyRevitOutputChartDataset(label)` Bases: `object` Chart dataset wrapper object. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
48
49
50
51
``` | ```md-code__content
def __init__(self, label):
self.label = label
self.data = []
self.backgroundColor = ''
``` | #### Attributes ##### `label = label``instance-attribute` ##### `data = []``instance-attribute` ##### `backgroundColor = ''``instance-attribute` #### Functions ##### `set_color(*args)` Set dataset color. Arguments are expected to be R, G, B, A values. Examples: ```md-code__content dataset_obj.set_color(0xFF, 0x8C, 0x8D, 0.8) ``` Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
``` | ````md-code__content
def set_color(self, *args):
"""Set dataset color.
Arguments are expected to be R, G, B, A values.
Examples:
```python
dataset_obj.set_color(0xFF, 0x8C, 0x8D, 0.8)
```
"""
if len(args) == 4:
self.backgroundColor = 'rgba({},{},{},{})'.format(args[0],
args[1],
args[2],
args[3])
elif len(args) == 1:
self.backgroundColor = '{}'.format(args[0])
```` | ### `PyRevitOutputChartData()` Bases: `object` Chart data wrapper object. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
74
75
76
``` | ```md-code__content
def __init__(self):
self.labels = ''
self.datasets = []
``` | #### Attributes ##### `labels = ''``instance-attribute` ##### `datasets = []``instance-attribute` #### Functions ##### `new_dataset(dataset_label)` Create new data set. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dataset_label` | `str` | dataset label | _required_ | Returns: | Type | Description | | --- | --- | | `PyRevitOutputChartDataset` | dataset wrapper object | Examples: ```md-code__content chart.data.new_dataset('set_a') ``` Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
``` | ````md-code__content
def new_dataset(self, dataset_label):
"""Create new data set.
Args:
dataset_label (str): dataset label
Returns:
(PyRevitOutputChartDataset): dataset wrapper object
Examples:
```python
chart.data.new_dataset('set_a')
```
"""
new_dataset = PyRevitOutputChartDataset(dataset_label)
self.datasets.append(new_dataset)
return new_dataset
```` | ### `PyRevitOutputChart(output, chart_type=LINE_CHART, version=None)` Bases: `object` Chart wrapper object for output window. Attributes: | Name | Type | Description | | --- | --- | --- | | `output` | `PyRevitOutputWindow` | output window wrapper object | | `chart_type` | `str` | chart type name | Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
105
106
107
108
109
110
111
112
113
114
``` | ```md-code__content
def __init__(self, output, chart_type=LINE_CHART, version=None):
self._output = output
self._style = None
self._width = self._height = None
self._version = version or '2.8.0'
self.type = chart_type
self.data = PyRevitOutputChartData()
self.options = PyRevitOutputChartOptions()
``` | #### Attributes ##### `type = chart_type``instance-attribute` ##### `data = PyRevitOutputChartData()``instance-attribute` ##### `options = PyRevitOutputChartOptions()``instance-attribute` #### Functions ##### `randomize_colors()` Randomize chart datasets colors. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
192
193
194
195
196
197
198
199
200
``` | ```md-code__content
def randomize_colors(self):
"""Randomize chart datasets colors."""
if self.type in [POLAR_CHART, PIE_CHART, DOUGHNUT_CHART]:
for dataset in self.data.datasets:
dataset.backgroundColor = [random_rgba_color()
for _ in range(0, len(dataset.data))]
else:
for dataset in self.data.datasets:
dataset.backgroundColor = random_rgba_color()
``` | ##### `set_width(width)` Set chart width on output window. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
202
203
204
``` | ```md-code__content
def set_width(self, width):
"""Set chart width on output window."""
self._width = width
``` | ##### `set_height(height)` Set chart height on output window. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
206
207
208
``` | ```md-code__content
def set_height(self, height):
"""Set chart height on output window."""
self._height = height
``` | ##### `set_style(html_style)` Set chart styling. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `html_style` | `str` | inline html css styling string | _required_ | Examples: ```md-code__content chart.set_style('height:150px') ``` Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
210
211
212
213
214
215
216
217
218
219
220
221
``` | ````md-code__content
def set_style(self, html_style):
"""Set chart styling.
Args:
html_style (str): inline html css styling string
Examples:
```python
chart.set_style('height:150px')
```
"""
self._style = html_style
```` | ##### `draw()` Request chart to draw itself on output window. Source code in `pyrevitlib/pyrevit/coreutils/charts.py` | | | | --- | --- | | ```
223
224
225
226
227
228
229
230
231
232
``` | ```md-code__content
def draw(self):
"""Request chart to draw itself on output window."""
self._setup_charts()
# setup canvas
canvas_id = self._make_canvas_unique_id()
canvas_code = self._make_canvas_code(canvas_id)
self._output.print_html(canvas_code)
# make the code
js_code = self._make_charts_script(canvas_id)
self._output.inject_script(js_code, body=True)
``` | ## Functions Back to top ## PyRevit Unit Tests [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/unittests/runner/#pyrevit.unittests.runner) # runner Unit tests facility. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `DEBUG_OKAY_RESULT = 'PASSED'``module-attribute` ### `DEBUG_FAIL_RESULT = 'FAILED'``module-attribute` ### `RESULT_TEST_SUITE_START = '
Test Suite: {suite}
'``module-attribute` ### `RESULT_DIV_OKAY = '
:white_heavy_check_mark: PASSED {test}
'``module-attribute` ### `RESULT_DIV_FAIL = '
:cross_mark: FAILED {test}
'``module-attribute` ### `RESULT_DIV_ERROR = '
:heavy_large_circle: ERROR {test}
'``module-attribute` ## Classes ### `OutputWriter()` Output writer for tests results. Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
35
36
``` | ```md-code__content
def __init__(self):
self._output = get_output()
``` | #### Functions ##### `write(output_str)` Prints the results to the output window. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `output_str` | `str` | Text to output | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
38
39
40
41
42
43
44
``` | ```md-code__content
def write(self, output_str):
"""Prints the results to the output window.
Args:
output_str (str): Text to output
"""
self._output.print_html(output_str)
``` | ### `PyRevitTestResult(verbosity)` Bases: `TestResult` Pyrevit Test Result. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `verbosity` | `int` | verbosity level. | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
53
54
55
``` | ```md-code__content
def __init__(self, verbosity):
super(PyRevitTestResult, self).__init__(verbosity=verbosity)
self.writer = OutputWriter()
``` | #### Attributes ##### `writer = OutputWriter()``instance-attribute` #### Functions ##### `getDescription(test)``staticmethod` Returns the description of the test. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestCase` | Unit test. | _required_ | Returns: | Type | Description | | --- | --- | | `str` | test description | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
57
58
59
60
61
62
63
64
65
66
67
``` | ```md-code__content
@staticmethod
def getDescription(test):
"""Returns the description of the test.
Args:
test (TestCase): Unit test.
Returns:
(str): test description
"""
return test.shortDescription() or test
``` | ##### `startTest(test)` Starts the test. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestCase` | unit test | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
69
70
71
72
73
74
75
76
``` | ```md-code__content
def startTest(self, test):
"""Starts the test.
Args:
test (TestCase): unit test
"""
super(PyRevitTestResult, self).startTest(test)
mlogger.debug('Running test: %s', self.getDescription(test))
``` | ##### `addSuccess(test)` Adds a test success. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestCase` | unit test case | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
78
79
80
81
82
83
84
85
86
87
``` | ```md-code__content
def addSuccess(self, test):
"""Adds a test success.
Args:
test (TestCase): unit test case
"""
super(PyRevitTestResult, self).addSuccess(test)
mlogger.debug(DEBUG_OKAY_RESULT)
self.writer.write(RESULT_DIV_OKAY
.format(test=self.getDescription(test)))
``` | ##### `addError(test, err)` Adds a test error. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestCase` | unit test case | _required_ | | `err` | `OptExcInfo` | test exception info | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
89
90
91
92
93
94
95
96
97
98
99
``` | ```md-code__content
def addError(self, test, err):
"""Adds a test error.
Args:
test (TestCase): unit test case
err (OptExcInfo): test exception info
"""
super(PyRevitTestResult, self).addError(test, err)
mlogger.debug(DEBUG_FAIL_RESULT)
self.writer.write(RESULT_DIV_ERROR
.format(test=self.getDescription(test)))
``` | ##### `addFailure(test, err)` Adds a test failure. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestCase` | unit test case | _required_ | | `err` | `OptExcInfo` | test exception info | _required_ | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
101
102
103
104
105
106
107
108
109
110
111
``` | ```md-code__content
def addFailure(self, test, err):
"""Adds a test failure.
Args:
test (TestCase): unit test case
err (OptExcInfo): test exception info
"""
super(PyRevitTestResult, self).addFailure(test, err)
mlogger.debug(DEBUG_FAIL_RESULT)
self.writer.write(RESULT_DIV_FAIL
.format(test=self.getDescription(test)))
``` | ### `PyRevitTestRunner(verbosity=1, failfast=False, use_buffer=False, resultclass=None)` Bases: `object` Test runner. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `verbosity` | `int` | level of vermosity. Defaults to 1. | `1` | | `failfast` | `bool` | if True, stops at the first failure. Defaults to False. | `False` | | `use_buffer` | `bool` | use a buffer. Defaults to False. | `False` | | `resultclass` | `type` | Class to use to hold the results.
Defaults to `PyRevitTestResult`. | `None` | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
135
136
137
138
139
140
141
``` | ```md-code__content
def __init__(self, verbosity=1, failfast=False,
use_buffer=False, resultclass=None):
self.verbosity = verbosity
self.failfast = failfast
self.use_buffer = use_buffer
if resultclass is not None:
self.resultclass = resultclass
``` | #### Attributes ##### `resultclass = PyRevitTestResult``class-attribute``instance-attribute` ##### `verbosity = verbosity``instance-attribute` ##### `failfast = failfast``instance-attribute` ##### `use_buffer = use_buffer``instance-attribute` #### Functions ##### `run(test)` Runs a test suite. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test` | `TestSuite` | Test suite to run | _required_ | Returns: | Type | Description | | --- | --- | | `PyRevitTestResult` | Test suite results. | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
``` | ```md-code__content
def run(self, test):
"""Runs a test suite.
Args:
test (TestSuite): Test suite to run
Returns:
(PyRevitTestResult): Test suite results.
"""
# setup results object
result = self._make_result()
result.failfast = self.failfast
result.buffer = self.use_buffer
# start clock
start_time = time.time()
# find run test methods
start_test_run = getattr(result, 'startTestRun', None)
if start_test_run is not None:
start_test_run()
try:
test(result)
finally:
stop_test_run = getattr(result, 'stopTestRun', None)
if stop_test_run is not None:
stop_test_run()
# stop clock and calculate run time
stop_time = time.time()
time_taken = stop_time - start_time
# print errots
result.printErrors()
test_count = result.testsRun
mlogger.debug("Ran %d test%s in %.3fs",
test_count, test_count != 1 and "s" or "", time_taken)
expected_fails = unexpected_successes = skipped = 0
try:
results = map(len, (result.expectedFailures,
result.unexpectedSuccesses,
result.skipped))
except AttributeError:
pass
else:
expected_fails, unexpected_successes, skipped = results
infos = []
if not result.wasSuccessful():
mlogger.debug("FAILED")
failed, errored = map(len, (result.failures, result.errors))
if failed:
infos.append("failures=%d" % failed)
if errored:
infos.append("errors=%d" % errored)
else:
mlogger.debug(DEBUG_OKAY_RESULT)
if skipped:
infos.append("skipped=%d" % skipped)
if expected_fails:
infos.append("expected failures=%d" % expected_fails)
if unexpected_successes:
infos.append("unexpected successes=%d" % unexpected_successes)
if infos:
mlogger.debug(" (%s)", (", ".join(infos),))
return result
``` | ## Functions ### `run_module_tests(test_module)` Runs the unit tests of the given module. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test_module` | `module` | module with tests | _required_ | Returns: | Type | Description | | --- | --- | | `PyRevitTestResult` | tests results. | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
``` | ```md-code__content
def run_module_tests(test_module):
"""Runs the unit tests of the given module.
Args:
test_module (module): module with tests
Returns:
(PyRevitTestResult): tests results.
"""
test_runner = PyRevitTestRunner()
test_loader = TestLoader()
# load all testcases from the given module into a testsuite
test_suite = test_loader.loadTestsFromModule(test_module)
# run the test suite
mlogger.debug('Running test suite for module: %s', test_module)
OutputWriter()\
.write(RESULT_TEST_SUITE_START.format(suite=test_module.__name__))
return test_runner.run(test_suite)
``` | ### `run_test_case(test_case)` Runs the unit test of the given TestCase class. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `test_case` | `type[TestCase]` | TestCase class with tests | _required_ | Returns: | Type | Description | | --- | --- | | `PyRevitTestResult` | tests results. | Source code in `pyrevitlib/pyrevit/unittests/runner.py` | | | | --- | --- | | ```
237
238
239
240
241
242
243
244
245
246
247
248
249
250
``` | ```md-code__content
def run_test_case(test_case):
"""Runs the unit test of the given TestCase class.
Args:
test_case (type[TestCase]): TestCase class with tests
Returns:
(PyRevitTestResult): tests results.
"""
test_runner = PyRevitTestRunner()
suite = TestLoader().loadTestsFromTestCase(test_case)
OutputWriter()\
.write(RESULT_TEST_SUITE_START.format(suite=suite.__class__.__name__))
return test_runner.run(suite)
``` | Back to top ## PyRevit Upgrade Functions [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/versionmgr/upgrade/#pyrevit.versionmgr.upgrade) # upgrade Perform upgrades between version, e.g. adding a new config parameter. ## Functions ### `upgrade_user_config(user_config)` Upgarde user configurations. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `user_config` | | obj: `pyrevit.userconfig.PyRevitConfig`): config object | _required_ | Source code in `pyrevitlib/pyrevit/versionmgr/upgrade.py` | | | | --- | --- | | ```
9
10
11
12
13
14
15
16
17
18
``` | ```md-code__content
def upgrade_user_config(user_config): #pylint: disable=W0613
"""Upgarde user configurations.
Args:
user_config (:obj:`pyrevit.userconfig.PyRevitConfig`): config object
"""
# upgrade value formats
for section in user_config:
for option in section:
setattr(section, option, getattr(section, option))
``` | ### `remove_leftover_temp_files()` 4.8.5 had a bug that would create temp files with extension ..bak. This cleans them up. Source code in `pyrevitlib/pyrevit/versionmgr/upgrade.py` | | | | --- | --- | | ```
21
22
23
24
25
26
27
28
29
30
``` | ```md-code__content
def remove_leftover_temp_files():
"""4.8.5 had a bug that would create temp files with extension ..bak.
This cleans them up.
"""
univ_path = op.dirname(appdata.get_universal_data_file("X", 'bak'))
if op.exists(univ_path):
for entry in os.listdir(univ_path):
if op.isfile(entry) and entry.lower().endswith('..bak'):
appdata.garbage_data_file(op.join(univ_path, entry))
``` | ### `upgrade_existing_pyrevit()` Upgrade existing pyRevit deployment. Source code in `pyrevitlib/pyrevit/versionmgr/upgrade.py` | | | | --- | --- | | ```
33
34
35
``` | ```md-code__content
def upgrade_existing_pyrevit():
"""Upgrade existing pyRevit deployment."""
remove_leftover_temp_files()
``` | Back to top ## Extension Manager [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/extensionmgr/#pyrevit.extensions.extensionmgr) # extensionmgr Find, parse and cache extensions. There are two types of extensions: UI Extensions (components.Extension) and Library Extensions (components.LibraryExtension). This module, finds the ui extensions installed and parses their directory for tools or loads them from cache. It also finds the library extensions and adds their directory address to the ui extensions so the python tools can use the shared libraries. To do its job correctly, this module needs to communicate with pyrevit.userconfig to get a list of user extension folder and also pyrevit.extensions.extpackages to check whether an extension is active or not. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Classes ## Functions ### `get_thirdparty_extension_data()` Returns all installed and active UI and Library extensions (not parsed). Returns: | Type | Description | | --- | --- | | `list` | list of components.Extension or components.LibraryExtension | Source code in `pyrevitlib/pyrevit/extensions/extensionmgr.py` | | | | --- | --- | | ```
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
``` | ```md-code__content
def get_thirdparty_extension_data():
"""Returns all installed and active UI and Library extensions (not parsed).
Returns:
(list): list of components.Extension or components.LibraryExtension
"""
# FIXME: reorganzie this code to use one single method to collect
# extension data for both lib and ui
ext_data_list = []
for root_dir in user_config.get_thirdparty_ext_root_dirs():
ext_data_list.extend(
[ui_ext for ui_ext in parse_dir_for_ext_type(root_dir,
Extension)])
ext_data_list.extend(
[lib_ext for lib_ext in parse_dir_for_ext_type(root_dir,
LibraryExtension)])
return _remove_disabled_extensions(ext_data_list)
``` | ### `get_installed_lib_extensions(root_dir)` Returns all the installed and active Library extensions (not parsed). Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `root_dir` | `str` | Extensions directory address | _required_ | Returns: | Type | Description | | --- | --- | | `list[LibraryExtension]` | list of components.LibraryExtension objects | Source code in `pyrevitlib/pyrevit/extensions/extensionmgr.py` | | | | --- | --- | | ```
128
129
130
131
132
133
134
135
136
137
138
139
140
``` | ```md-code__content
def get_installed_lib_extensions(root_dir):
"""Returns all the installed and active Library extensions (not parsed).
Args:
root_dir (str): Extensions directory address
Returns:
(list[LibraryExtension]): list of components.LibraryExtension objects
"""
lib_ext_list = \
[lib_ext for lib_ext in parse_dir_for_ext_type(root_dir,
LibraryExtension)]
return _remove_disabled_extensions(lib_ext_list)
``` | ### `get_installed_ui_extensions()` Returns all UI extensions (fully parsed) under the given directory. This will also process the Library extensions and will add their path to the syspath of the UI extensions. Returns: | Type | Description | | --- | --- | | `list[Extension]` | list of components.Extension objects | Source code in `pyrevitlib/pyrevit/extensions/extensionmgr.py` | | | | --- | --- | | ```
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
``` | ```md-code__content
def get_installed_ui_extensions():
"""Returns all UI extensions (fully parsed) under the given directory.
This will also process the Library extensions and will add
their path to the syspath of the UI extensions.
Returns:
(list[Extension]): list of components.Extension objects
"""
ui_ext_list = []
lib_ext_list = []
# get a list of all directories that could include extensions
ext_search_dirs = user_config.get_ext_root_dirs()
mlogger.debug('Extension Directories: %s', ext_search_dirs)
# collect all library extensions. Their dir paths need to be added
# to sys.path for all commands
for root_dir in ext_search_dirs:
lib_ext_list.extend(get_installed_lib_extensions(root_dir))
# Get a list of all installed extensions in this directory
# _parser.parse_dir_for_ext_type() returns a list of extensions
# in given directory
for root_dir in ext_search_dirs:
for ext_info in parse_dir_for_ext_type(root_dir, Extension):
# test if cache is valid for this ui_extension
# it might seem unusual to create a ui_extension and then
# re-load it from cache but minimum information about the
# ui_extension needs to be passed to the cache module for proper
# hash calculation and ui_extension recovery. at this point
# `ui_extension` does not include any sub-components
# (e.g, tabs, panels, etc) ui_extension object is very small and
# its creation doesn't add much overhead.
if _is_extension_enabled(ext_info):
ui_extension = _parse_or_cache(ext_info)
ui_ext_list.append(ui_extension)
else:
mlogger.debug('Skipping disabled ui extension: %s',
ext_info.name)
# update extension master syspaths with standard pyrevit lib paths and
# lib address of other lib extensions (to support extensions that provide
# library only to be used by other extensions)
# all other lib paths internal to the extension and tool bundles have
# already been set inside the extension bundles and will take precedence
# over paths added by this method (they're the first paths added to the
# search paths list, and these paths will follow)
for ui_extension in ui_ext_list:
_update_extension_search_paths(
ui_extension,
lib_ext_list,
[MAIN_LIB_DIR, MISC_LIB_DIR]
)
return ui_ext_list
``` | Back to top ## pyRevit Git Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/git/#pyrevit.coreutils.git) # git LibGit2Sharp wrapper module for pyRevit. Documentation https://github.com/libgit2/libgit2sharp/wiki ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `GIT_LIB = 'LibGit2Sharp'``module-attribute` ### `LIBGIT_DLL = framework.get_dll_file(GIT_LIB)``module-attribute` ## Classes ### `PyRevitGitAuthenticationError` Bases: `PyRevitException` Git authentication error. #### Attributes ##### `msg``property` Return exception message. ### `RepoInfo(repo)` Bases: `object` Repo wrapper for passing around repository information. Attributes: | Name | Type | Description | | --- | --- | --- | | `directory` | `str` | repo directory | | `name` | `str` | repo name | | `head_name` | `str` | head branch name | | `last_commit_hash` | `str` | hash of head commit | | `repo` | `str` | `LibGit2Sharp.Repository` object | | `branch` | `str` | current branch name | | `username` | `str` | credentials - username | | `password` | `str` | credentials - password | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
60
61
62
63
64
65
66
67
``` | ```md-code__content
def __init__(self, repo):
self.directory = repo.Info.WorkingDirectory
self.name = op.basename(op.normpath(self.directory))
self.head_name = repo.Head.FriendlyName
self.last_commit_hash = repo.Head.Tip.Id.Sha
self.repo = repo
self.branch = repo.Head.FriendlyName
self.username = self.password = None
``` | #### Attributes ##### `directory = repo.Info.WorkingDirectory``instance-attribute` ##### `name = op.basename(op.normpath(self.directory))``instance-attribute` ##### `head_name = repo.Head.FriendlyName``instance-attribute` ##### `last_commit_hash = repo.Head.Tip.Id.Sha``instance-attribute` ##### `repo = repo``instance-attribute` ##### `branch = repo.Head.FriendlyName``instance-attribute` ##### `username = None``instance-attribute` ##### `password = None``instance-attribute` ## Functions ### `get_repo(repo_dir)` Return repo object for given git repo directory. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_dir` | `str` | full path of git repo directory | _required_ | Returns: | Type | Description | | --- | --- | | `RepoInfo` | repo object | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
145
146
147
148
149
150
151
152
153
154
155
``` | ```md-code__content
def get_repo(repo_dir):
"""Return repo object for given git repo directory.
Args:
repo_dir (str): full path of git repo directory
Returns:
(RepoInfo): repo object
"""
repo = libgit.Repository(repo_dir)
return RepoInfo(repo)
``` | ### `git_pull(repo_info)` Pull the current head of given repo. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | `RepoInfo` | target repo object | _required_ | Returns: | Type | Description | | --- | --- | | `RepoInfo` | repo object with updated head | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
``` | ```md-code__content
def git_pull(repo_info):
"""Pull the current head of given repo.
Args:
repo_info (RepoInfo): target repo object
Returns:
(RepoInfo): repo object with updated head
"""
repo = repo_info.repo
try:
libgit.Commands.Pull(repo,
_make_pull_signature(),
_make_pull_options(repo_info))
mlogger.debug('Successfully pulled repo: %s', repo_info.directory)
head_msg = safe_strtype(repo.Head.Tip.Message).replace('\n', '')
mlogger.debug('New head is: %s > %s', repo.Head.Tip.Id.Sha, head_msg)
return RepoInfo(repo)
except Exception as pull_err:
mlogger.debug('Failed git pull: %s | %s', repo_info.directory, pull_err)
_process_git_error(pull_err)
``` | ### `git_fetch(repo_info)` Fetch current branch of given repo. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | `RepoInfo` | target repo object | _required_ | Returns: | Type | Description | | --- | --- | | `RepoInfo` | repo object with updated head | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
``` | ```md-code__content
def git_fetch(repo_info):
"""Fetch current branch of given repo.
Args:
repo_info (RepoInfo): target repo object
Returns:
(RepoInfo): repo object with updated head
"""
repo = repo_info.repo
try:
libgit.Commands.Fetch(repo,
repo.Head.TrackedBranch.RemoteName,
[],
_make_fetch_options(repo_info),
'fetching pyrevit updates')
mlogger.debug('Successfully pulled repo: %s', repo_info.directory)
head_msg = safe_strtype(repo.Head.Tip.Message).replace('\n', '')
mlogger.debug('New head is: %s > %s', repo.Head.Tip.Id.Sha, head_msg)
return RepoInfo(repo)
except Exception as fetch_err:
mlogger.debug('Failed git fetch: %s | %s',
repo_info.directory, fetch_err)
_process_git_error(fetch_err)
``` | ### `git_clone(repo_url, clone_dir, username=None, password=None)` Clone git repository to given location. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_url` | `str` | repo .git url | _required_ | | `clone_dir` | `str` | destination path | _required_ | | `username` | `str` | credentials - username | `None` | | `password` | `str` | credentials - password | `None` | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
``` | ```md-code__content
def git_clone(repo_url, clone_dir, username=None, password=None):
"""Clone git repository to given location.
Args:
repo_url (str): repo .git url
clone_dir (str): destination path
username (str): credentials - username
password (str): credentials - password
"""
try:
libgit.Repository.Clone(repo_url,
clone_dir,
_make_clone_options(username=username,
password=password))
mlogger.debug('Completed git clone: %s @ %s', repo_url, clone_dir)
except Exception as clone_err:
mlogger.debug('Error cloning repo: %s to %s | %s',
repo_url, clone_dir, clone_err)
_process_git_error(clone_err)
``` | ### `compare_branch_heads(repo_info)` Compare local and remote branch heads and return ??? Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | `RepoInfo` | target repo object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
``` | ```md-code__content
def compare_branch_heads(repo_info):
"""Compare local and remote branch heads and return ???
Args:
repo_info (RepoInfo): target repo object
"""
# FIXME: need return type. possibly simplify
repo = repo_info.repo
repo_branches = repo.Branches
mlogger.debug('Repo branches: %s', [b.FriendlyName for b in repo_branches])
for branch in repo_branches:
if branch.FriendlyName == repo_info.branch and not branch.IsRemote:
try:
if branch.TrackedBranch:
mlogger.debug('Comparing heads: %s of %s',
branch.CanonicalName,
branch.TrackedBranch.CanonicalName)
hist_div = repo.ObjectDatabase. \
CalculateHistoryDivergence(branch.Tip,
branch.TrackedBranch.Tip)
return hist_div
except Exception as compare_err:
mlogger.error('Can not compare branch %s in repo: %s | %s',
branch,
repo,
safe_strtype(compare_err).replace('\n', ''))
else:
mlogger.debug('Skipping remote branch: %s', branch.CanonicalName)
``` | ### `get_all_new_commits(repo_info)` Fetch and return new commits ahead of current head. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | `RepoInfo` | target repo object | _required_ | Returns: | Type | Description | | --- | --- | | `OrderedDict[str, str]` | ordered dict of commit hash:message | Source code in `pyrevitlib/pyrevit/coreutils/git.py` | | | | --- | --- | | ```
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
``` | ```md-code__content
def get_all_new_commits(repo_info):
"""Fetch and return new commits ahead of current head.
Args:
repo_info (RepoInfo): target repo object
Returns:
(OrderedDict[str, str]): ordered dict of commit hash:message
"""
repo = repo_info.repo
current_commit = repo_info.last_commit_hash
ref_commit = repo.Lookup(libgit.ObjectId(current_commit),
libgit.ObjectType.Commit)
# Let's only consider the refs that lead to this commit...
refs = repo.Refs.ReachableFrom([ref_commit])
# ...and create a filter that will retrieve all the commits...
commit_filter = libgit.CommitFilter()
commit_filter.IncludeReachableFrom = refs
commit_filter.ExcludeReachableFrom = ref_commit
commit_filter.SortBy = libgit.CommitSortStrategies.Time
commits = repo.Commits.QueryBy(commit_filter)
commitsdict = OrderedDict()
for commit in commits:
if commit in repo.Head.Commits \
or commit in repo.Head.TrackedBranch.Commits:
commitsdict[commit.Id.ToString()] = commit.MessageShort
return commitsdict
``` | Back to top ## Revit DB Object Wrappers [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/db/#pyrevit.revit.db) # db Revit DB objects wrappers. ## Attributes ## Classes ### `BaseWrapper(obj=None)` Bases: `object` Base revit databse object wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
20
21
``` | ```md-code__content
def __init__(self, obj=None):
self._wrapped = obj
``` | #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `ElementWrapper(element)` Bases: `BaseWrapper` Revit element wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
62
63
64
65
66
``` | ```md-code__content
def __init__(self, element):
super(ElementWrapper, self).__init__(element)
if not isinstance(self._wrapped, DB.Element):
raise PyRevitException('Can not wrap object that are not '
'derived from Element.')
``` | #### Attributes ##### `assoc_doc``property` ##### `name``property` ##### `symbol_name``property` ##### `family_name``property` ##### `id``property` ##### `unique_id``property` ##### `workset_id``property` ##### `mark``property` ##### `location``property` ##### `x``property` ##### `y``property` ##### `z``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ##### `get_param(param_name)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
126
127
``` | ```md-code__content
def get_param(self, param_name):
return self._wrapped.LookupParameter(param_name)
``` | ##### `safe_get_param(param_name, default=None)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
129
130
131
132
133
``` | ```md-code__content
def safe_get_param(self, param_name, default=None):
try:
return self._wrapped.LookupParameter(param_name)
except Exception:
return default
``` | ### `ExternalRef(link, extref)` Bases: `ElementWrapper` External reference wraper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
138
139
140
``` | ```md-code__content
def __init__(self, link, extref):
super(ExternalRef, self).__init__(link)
self._extref = extref
``` | #### Attributes ##### `assoc_doc``property` ##### `symbol_name``property` ##### `family_name``property` ##### `id``property` ##### `unique_id``property` ##### `workset_id``property` ##### `mark``property` ##### `location``property` ##### `x``property` ##### `y``property` ##### `z``property` ##### `name``property` ##### `link``property` ##### `linktype``property` ##### `path``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ##### `get_param(param_name)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
126
127
``` | ```md-code__content
def get_param(self, param_name):
return self._wrapped.LookupParameter(param_name)
``` | ##### `safe_get_param(param_name, default=None)` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
129
130
131
132
133
``` | ```md-code__content
def safe_get_param(self, param_name, default=None):
try:
return self._wrapped.LookupParameter(param_name)
except Exception:
return default
``` | ##### `reload()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
159
160
``` | ```md-code__content
def reload(self):
return self._wrapped.Reload()
``` | ### `ProjectParameter(param_def, param_binding=None, param_ext_def=False)` Bases: `BaseWrapper` Project parameter wrapper. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
``` | ```md-code__content
def __init__(self, param_def, param_binding=None, param_ext_def=False):
super(ProjectParameter, self).__init__()
self.param_def = param_def
self.param_binding = param_binding
self.param_binding_type = self._determine_binding_type()
self.shared = False
self.param_ext_def = None
self.param_guid = ''
if param_ext_def:
self.shared = True
self.param_ext_def = param_ext_def
self.param_guid = self.param_ext_def.GUID.ToString()
self.name = self.param_def.Name
# Revit <2017 does not have the Id parameter
self.param_id = getattr(self.param_def, 'Id', None)
if HOST_APP.is_exactly(2021):
# Revit >2021 does not have the UnitType property
self.unit_type = self.param_def.GetSpecTypeId()
self.param_type = self.param_def.ParameterType
self.param_group = self.param_def.ParameterGroup
elif HOST_APP.is_newer_than(2022, or_equal=True):
# GetSpecTypeId() Removed in Revit 2022
self.unit_type = self.param_def.GetDataType()
# Revit >2022 does not have the ParameterType property
self.param_type = self.param_def.GetDataType()
# ParameterGroup deprecated
self.param_group = self.param_def.GetGroupTypeId().TypeId
else:
self.unit_type = self.param_def.UnitType
self.param_type = self.param_def.ParameterType
self.param_group = self.param_def.ParameterGroup
``` | #### Attributes ##### `param_def = param_def``instance-attribute` ##### `param_binding = param_binding``instance-attribute` ##### `param_binding_type = self._determine_binding_type()``instance-attribute` ##### `shared = False``instance-attribute` ##### `param_ext_def = None``instance-attribute` ##### `param_guid = ''``instance-attribute` ##### `name = self.param_def.Name``instance-attribute` ##### `param_id = getattr(self.param_def, 'Id', None)``instance-attribute` ##### `unit_type = self.param_def.GetSpecTypeId()``instance-attribute` ##### `param_type = self.param_def.ParameterType``instance-attribute` ##### `param_group = self.param_def.ParameterGroup``instance-attribute` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `ProjectInfo(doc)` Bases: `BaseWrapper` Project information. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
221
222
223
``` | ```md-code__content
def __init__(self, doc):
super(ProjectInfo, self).__init__()
self._doc = doc
``` | #### Attributes ##### `name``property` ##### `number``property` ##### `address``property` ##### `author``property` ##### `building_name``property` ##### `client_name``property` ##### `issue_date``property` ##### `org_name``property` ##### `org_desc``property` ##### `status``property` ##### `location``property` ##### `path``property` ##### `filename``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ### `XYZPoint(obj=None)` Bases: `BaseWrapper` Wrapper for XYZ point. Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
20
21
``` | ```md-code__content
def __init__(self, obj=None):
self._wrapped = obj
``` | #### Attributes ##### `x``property` ##### `y``property` ##### `z``property` #### Functions ##### `unwrap()` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
39
40
``` | ```md-code__content
def unwrap(self):
return self._wrapped
``` | ##### `compare_attr(src, dest, attr_name, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
49
``` | ```md-code__content
@staticmethod
def compare_attr(src, dest, attr_name, case_sensitive=False):
if case_sensitive:
return safe_strtype(getattr(src, attr_name, '')).lower() == \
safe_strtype(getattr(dest, attr_name, '')).lower()
else:
return safe_strtype(getattr(src, attr_name)) == \
safe_strtype(getattr(dest, attr_name))
``` | ##### `compare_attrs(src, dest, attr_names, case_sensitive=False)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/db/__init__.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
``` | ```md-code__content
@staticmethod
def compare_attrs(src, dest, attr_names, case_sensitive=False):
return [BaseWrapper.compare_attr(src,
dest,
x,
case_sensitive=case_sensitive)
for x in attr_names]
``` | ## Functions Back to top ## pyRevit Bundle Type Maker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/bundletypemaker/#pyrevit.runtime.bundletypemaker) # bundletypemaker Create necessary compiled types for pyRevit bundles. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_bundle_type(module_builder, type_name, bundle_script, bundle_config_script, bundle_search_paths, bundle_arguments, bundle_help_url, bundle_tooltip, bundle_name, bundle_full_name, bundle_extension_name, bundle_unique_name, bundle_control_id, bundle_context, engine_cfgs)` Source code in `pyrevitlib/pyrevit/runtime/bundletypemaker.py` | | | | --- | --- | | ```
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
``` | ```md-code__content
def create_bundle_type(
module_builder,
type_name,
bundle_script,
bundle_config_script,
bundle_search_paths,
bundle_arguments,
bundle_help_url,
bundle_tooltip,
bundle_name,
bundle_full_name,
bundle_extension_name,
bundle_unique_name,
bundle_control_id,
bundle_context,
engine_cfgs,
):
runtime.create_type(
module_builder,
runtime.CMD_EXECUTOR_TYPE,
type_name,
runtime.create_ext_command_attrs(),
bundle_script,
bundle_config_script,
coreutils.join_strings(bundle_search_paths),
coreutils.join_strings(bundle_arguments),
bundle_help_url,
bundle_tooltip,
bundle_name,
bundle_full_name,
bundle_extension_name,
bundle_unique_name,
bundle_control_id,
bundle_context,
engine_cfgs)
``` | ### `create_executor_type(extension, module_builder, cmd_component, eng_cfgs='')` Source code in `pyrevitlib/pyrevit/runtime/bundletypemaker.py` | | | | --- | --- | | ```
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
``` | ```md-code__content
def create_executor_type(extension, module_builder, cmd_component, eng_cfgs=''):
mlogger.debug('Creating executor type for: %s', cmd_component)
mlogger.debug('%s uses clean engine: %s',
cmd_component.name, cmd_component.requires_clean_engine)
mlogger.debug('%s requires Fullframe engine: %s',
cmd_component.name, cmd_component.requires_fullframe_engine)
mlogger.debug('%s requires Fullframe engine: %s',
cmd_component.name, cmd_component.requires_fullframe_engine)
create_bundle_type(
module_builder=module_builder,
type_name=cmd_component.unique_name,
bundle_script=cmd_component.script_file or "",
bundle_config_script=cmd_component.config_script_file or "",
bundle_search_paths=cmd_component.module_paths,
bundle_arguments=cmd_component.arguments,
bundle_help_url=cmd_component.help_url or "",
bundle_tooltip=cmd_component.tooltip or "",
bundle_name=cmd_component.name,
bundle_full_name=cmd_component.get_full_bundle_name(),
bundle_extension_name=extension.name,
bundle_unique_name=cmd_component.unique_name,
bundle_control_id=cmd_component.control_id,
bundle_context=cmd_component.context or "",
engine_cfgs=eng_cfgs
)
mlogger.debug('Successfully created executor type for: %s', cmd_component)
``` | ### `create_selection_avail_type(module_builder, cmd_component)` Source code in `pyrevitlib/pyrevit/runtime/bundletypemaker.py` | | | | --- | --- | | ```
80
81
82
83
84
85
``` | ```md-code__content
def create_selection_avail_type(module_builder, cmd_component):
runtime.create_type(module_builder,
runtime.CMD_AVAIL_TYPE_SELECTION,
cmd_component.avail_class_name,
[],
cmd_component.context)
``` | ### `create_zerodoc_avail_type(module_builder, cmd_component)` Source code in `pyrevitlib/pyrevit/runtime/bundletypemaker.py` | | | | --- | --- | | ```
88
89
90
91
92
``` | ```md-code__content
def create_zerodoc_avail_type(module_builder, cmd_component):
runtime.create_type(module_builder,
runtime.CMD_AVAIL_TYPE_ZERODOC,
cmd_component.avail_class_name,
[])
``` | ### `create_extended_avail_type(module_builder, cmd_component)` Source code in `pyrevitlib/pyrevit/runtime/bundletypemaker.py` | | | | --- | --- | | ```
95
96
97
98
99
100
``` | ```md-code__content
def create_extended_avail_type(module_builder, cmd_component):
runtime.create_type(module_builder,
runtime.CMD_AVAIL_TYPE_EXTENDED,
cmd_component.avail_class_name,
[],
cmd_component.context)
``` | Back to top ## pyRevit Project Information [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/versionmgr/about/#pyrevit.versionmgr.about) # about Utility module for pyRevit project information. Examples: ```md-code__content from pyrevit.versionmgr import about a = about.get_pyrevit_about() a.subtitle ``` 'python RAD Environment for Autodesk Revit®'a.copyright'© 2014-2025 Ehsan Iran-Nejad' ## Attributes ### `PyRevitAbout = namedtuple('PyRevitAbout', ['subtitle', 'madein', 'copyright'])``module-attribute` pyRevit project info tuple. Attributes: | Name | Type | Description | | --- | --- | --- | | `subtitle` | `str` | project subtitle | | `madein` | `str` | project made-in info | | `copyright` | `str` | project copyright info | ## Functions ### `get_pyrevit_about()` Return information about pyRevit project. Returns: | Type | Description | | --- | --- | | `PyRevitAbout` | pyRevit project info tuple | Source code in `pyrevitlib/pyrevit/versionmgr/about.py` | | | | --- | --- | | ```
26
27
28
29
30
31
32
33
34
``` | ```md-code__content
def get_pyrevit_about():
"""Return information about pyRevit project.
Returns:
(PyRevitAbout): pyRevit project info tuple
"""
return PyRevitAbout(subtitle='python RAD Environment for Autodesk Revit®',
madein="['pdx', 'hio', 'rno', 'sea']",
copyright='© 2014-2025 Ehsan Iran-Nejad')
``` | Back to top ## Preflight Test Case [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/preflight/case/#pyrevit.preflight.case) # case Base Preflight test class that defines the minimum interface. ## Classes ### `PreflightTestCase` Bases: `object` Base class for preflight tests. #### Functions ##### `setUp(doc, output)` Hook method for setting up the test before exercising it. Source code in `pyrevitlib/pyrevit/preflight/case.py` | | | | --- | --- | | ```
8
9
10
``` | ```md-code__content
def setUp(self, doc, output):
"""Hook method for setting up the test before exercising it."""
pass
``` | ##### `startTest(doc, output)` Hook method for exercising the test. Source code in `pyrevitlib/pyrevit/preflight/case.py` | | | | --- | --- | | ```
12
13
14
``` | ```md-code__content
def startTest(self, doc, output):
"""Hook method for exercising the test."""
pass
``` | ##### `tearDown(doc, output)` Hook method for deconstructing the test after testing it. Source code in `pyrevitlib/pyrevit/preflight/case.py` | | | | --- | --- | | ```
16
17
18
``` | ```md-code__content
def tearDown(self, doc, output):
"""Hook method for deconstructing the test after testing it."""
pass
``` | ##### `doCleanups(doc, output)` Execute all cleanup functions. Normally called after tearDown. Source code in `pyrevitlib/pyrevit/preflight/case.py` | | | | --- | --- | | ```
20
21
22
``` | ```md-code__content
def doCleanups(self, doc, output):
"""Execute all cleanup functions. Normally called after tearDown."""
pass
``` | Back to top ## Assembly Maker Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/loader/asmmaker/#pyrevit.loader.asmmaker) # asmmaker Assembly maker module. ## Attributes ### `ExtensionAssemblyInfo = namedtuple('ExtensionAssemblyInfo', ['name', 'location', 'reloading'])``module-attribute` ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_assembly(extension)` Create an extension assembly. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension. | _required_ | Returns: | Type | Description | | --- | --- | | `ExtensionAssemblyInfo` | assembly info | Source code in `pyrevitlib/pyrevit/loader/asmmaker.py` | | | | --- | --- | | ```
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
``` | ```md-code__content
def create_assembly(extension):
"""Create an extension assembly.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension.
Returns:
(ExtensionAssemblyInfo): assembly info
"""
mlogger.debug('Creating assembly for extension: %s', extension.name)
# create assembly file and return assembly path to be used in UI creation
# try:
ext_asm_info = _produce_asm_file(extension)
mlogger.debug('Assembly created: %s', ext_asm_info)
return ext_asm_info
``` | ### `cleanup_assembly_files()` Source code in `pyrevitlib/pyrevit/loader/asmmaker.py` | | | | --- | --- | | ```
209
210
211
212
213
214
215
216
``` | ```md-code__content
def cleanup_assembly_files():
if coreutils.get_revit_instance_count() == 1:
for asm_file_path in appdata.list_data_files(file_ext='dll'):
if not assmutils.find_loaded_asm(asm_file_path, by_location=True):
appdata.garbage_data_file(asm_file_path)
asm_log_file = asm_file_path.replace('.dll', '.log')
if op.exists(asm_log_file):
appdata.garbage_data_file(asm_log_file)
``` | Back to top ## YamlDotNet Wrapper [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/yaml/#pyrevit.coreutils.yaml) # yaml Wrapper for YamlDotNet. ## Attributes ## Functions ### `load(yaml_file)` Load Yaml file into YamlDotNet object. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `yaml_file` | `str` | file path to yaml file | _required_ | Returns: | Type | Description | | --- | --- | | `YamlMappingNode` | yaml node | Source code in `pyrevitlib/pyrevit/coreutils/yaml.py` | | | | --- | --- | | ```
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
``` | ```md-code__content
def load(yaml_file):
"""Load Yaml file into YamlDotNet object.
Args:
yaml_file (str): file path to yaml file
Returns:
(YamlDotNet.RepresentationModel.YamlMappingNode): yaml node
"""
if PY3:
with open(yaml_file, 'r', encoding="utf8") as yamlfile:
yamlstr = libyaml.RepresentationModel.YamlStream()
yamldata = yamlfile.read()
yamlstr.Load(StringReader(yamldata))
if yamlstr.Documents.Count >= 1:
return yamlstr.Documents[0].RootNode
else:
with open(yaml_file, 'r') as yamlfile:
yamlstr = libyaml.RepresentationModel.YamlStream()
yamldata = yamlfile.read().decode('utf-8')
yamlstr.Load(StringReader(yamldata))
if yamlstr.Documents.Count >= 1:
return yamlstr.Documents[0].RootNode
``` | ### `load_as_dict(yaml_file)` Load Yaml file into python dict object. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `yaml_file` | `str` | file path to yaml file | _required_ | Returns: | Type | Description | | --- | --- | | `dict[str, Any]` | dictionary representing yaml data | Source code in `pyrevitlib/pyrevit/coreutils/yaml.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
58
59
60
``` | ```md-code__content
def load_as_dict(yaml_file):
"""Load Yaml file into python dict object.
Args:
yaml_file (str): file path to yaml file
Returns:
(dict[str, Any]): dictionary representing yaml data
"""
return _convert_yamldotnet_to_dict(load(yaml_file))
``` | ### `dump_dict(dict_object, yaml_file)` Save YamlDotNet object to Yaml file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `dict_object` | `dict` | dict object to be serialized into yaml | _required_ | | `yaml_file` | `str` | file path to yaml file | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/yaml.py` | | | | --- | --- | | ```
63
64
65
66
67
68
69
70
71
72
73
``` | ```md-code__content
def dump_dict(dict_object, yaml_file):
"""Save YamlDotNet object to Yaml file.
Args:
dict_object (dict): dict object to be serialized into yaml
yaml_file (str): file path to yaml file
"""
ybuilder = libyaml.Serialization.SerializerBuilder().Build()
serialized_yaml = ybuilder.Serialize(dict_object)
with codecs.open(yaml_file, 'w', 'utf-8') as yamlfile:
yamlfile.write(serialized_yaml.replace('\r\n', '\n'))
``` | Back to top ## pyRevit AppData Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/appdata/#pyrevit.coreutils.appdata) # appdata Utility functions for creating data files within pyRevit environment. Most times, scripts need to save some data to share between different scripts that work on a similar topic or between script executions. This module provides the necessary and consistent mechanism for creating and maintaining such files. Examples: ```md-code__content from pyrevit.coreutils import appdata appdata.list_data_files() ``` ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `TEMP_FILE_EXT = 'tmp'``module-attribute` ## Functions ### `get_universal_data_file(file_id, file_ext, name_only=False)` Get path to file that is shared between all host versions. These data files are not cleaned up at Revit restart. e.g pyrevit\_pyrevitlabs\_file\_id.file\_ext Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | Unique identifier for the file | _required_ | | `file_ext` | `str` | File extension | _required_ | | `name_only` | `bool` | If true, function returns file name only | `False` | Returns: | Type | Description | | --- | --- | | `str` | File name or full file path (depending on name\_only) | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
``` | ```md-code__content
def get_universal_data_file(file_id, file_ext, name_only=False):
"""Get path to file that is shared between all host versions.
These data files are not cleaned up at Revit restart.
e.g pyrevit_pyrevitlabs_file_id.file_ext
Args:
file_id (str): Unique identifier for the file
file_ext (str): File extension
name_only (bool): If true, function returns file name only
Returns:
(str): File name or full file path (depending on name_only)
"""
return _get_app_file(file_id, file_ext,
filename_only=name_only, universal=True)
``` | ### `get_data_file(file_id, file_ext, name_only=False)` Get path to file that will not be cleaned up at Revit load. e.g pyrevit\_2016\_pyrevitlabs\_file\_id.file\_ext Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | Unique identifier for the file | _required_ | | `file_ext` | `str` | File extension | _required_ | | `name_only` | `bool` | If true, function returns file name only | `False` | Returns: | Type | Description | | --- | --- | | `str` | File name or full file path (depending on name\_only) | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
143
144
145
146
147
148
149
150
151
152
153
154
155
156
``` | ```md-code__content
def get_data_file(file_id, file_ext, name_only=False):
"""Get path to file that will not be cleaned up at Revit load.
e.g pyrevit_2016_pyrevitlabs_file_id.file_ext
Args:
file_id (str): Unique identifier for the file
file_ext (str): File extension
name_only (bool): If true, function returns file name only
Returns:
(str): File name or full file path (depending on name_only)
"""
return _get_app_file(file_id, file_ext, filename_only=name_only)
``` | ### `get_instance_data_file(file_id, file_ext=TEMP_FILE_EXT, name_only=False)` Get path to file that should be used by current instance only. These data files will be cleaned up at Revit restart. e.g pyrevit\_2016\_pyrevitlabs\_2353\_file\_id.file\_ext Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | Unique identifier for the file | _required_ | | `file_ext` | `str` | File extension | `TEMP_FILE_EXT` | | `name_only` | `bool` | If true, function returns file name only | `False` | Returns: | Type | Description | | --- | --- | | `str` | File name or full file path (depending on name\_only) | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
``` | ```md-code__content
def get_instance_data_file(file_id, file_ext=TEMP_FILE_EXT, name_only=False):
"""Get path to file that should be used by current instance only.
These data files will be cleaned up at Revit restart.
e.g pyrevit_2016_pyrevitlabs_2353_file_id.file_ext
Args:
file_id (str): Unique identifier for the file
file_ext (str): File extension
name_only (bool): If true, function returns file name only
Returns:
(str): File name or full file path (depending on name_only)
"""
return _get_app_file(file_id, file_ext,
filename_only=name_only, stamped=True)
``` | ### `is_pyrevit_data_file(file_name)` Check if given file is a pyRevit data file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_name` | `str` | file name | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if file is a pyRevit data file | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
177
178
179
180
181
182
183
184
185
186
``` | ```md-code__content
def is_pyrevit_data_file(file_name):
"""Check if given file is a pyRevit data file.
Args:
file_name (str): file name
Returns:
(bool): True if file is a pyRevit data file
"""
return pyrevit.PYREVIT_FILE_PREFIX in file_name
``` | ### `is_file_available(file_name, file_ext, universal=False)` Check if given file is available within appdata directory. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_name` | `str` | file name | _required_ | | `file_ext` | `str` | file extension | _required_ | | `universal` | `bool` | Check against universal data files | `False` | Returns: | Type | Description | | --- | --- | | `str | bool` | file path if file is available | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
``` | ```md-code__content
def is_file_available(file_name, file_ext, universal=False):
"""Check if given file is available within appdata directory.
Args:
file_name (str): file name
file_ext (str): file extension
universal (bool): Check against universal data files
Returns:
(str | bool): file path if file is available
"""
if universal:
full_filename = op.join(
pyrevit.PYREVIT_APP_DIR,
coreutils.make_canonical_name(file_name, file_ext))
else:
full_filename = op.join(
pyrevit.PYREVIT_VERSION_APP_DIR,
coreutils.make_canonical_name(file_name, file_ext))
if op.exists(full_filename):
return full_filename
else:
return False
``` | ### `is_data_file_available(file_id, file_ext)` Check if given file is available within appdata directory. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_id` | `str` | data file id | _required_ | | `file_ext` | `str` | file extension | _required_ | Returns: | Type | Description | | --- | --- | | `str` | file path if file is available | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
``` | ```md-code__content
def is_data_file_available(file_id, file_ext):
"""Check if given file is available within appdata directory.
Args:
file_id (str): data file id
file_ext (str): file extension
Returns:
(str): file path if file is available
"""
full_filename = _get_app_file(file_id, file_ext)
if op.exists(full_filename):
return full_filename
else:
return False
``` | ### `list_data_files(file_ext, universal=False)` List all data files with given extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | file extension | _required_ | | `universal` | `bool` | Check against universal data files | `False` | Returns: | Type | Description | | --- | --- | | `list[str]` | list of files | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
``` | ```md-code__content
def list_data_files(file_ext, universal=False):
"""List all data files with given extension.
Args:
file_ext (str): file extension
universal (bool): Check against universal data files
Returns:
(list[str]): list of files
"""
return _list_app_files(
pyrevit.PYREVIT_FILE_PREFIX,
file_ext,
universal=universal
)
``` | ### `list_instance_data_files(file_ext)` List all data files associated with current session. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | data files with this extension will be listed only. | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | list of data files | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
248
249
250
251
252
253
254
255
256
257
258
``` | ```md-code__content
def list_instance_data_files(file_ext):
"""List all data files associated with current session.
Args:
file_ext (str): data files with this extension will be listed only.
Returns:
(list[str]): list of data files
"""
return _list_app_files(pyrevit.PYREVIT_FILE_PREFIX_STAMPED, file_ext)
``` | ### `find_data_files(file_ext)` Find data files in all data files directories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | data files with this extension will be listed only | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | list of files | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
``` | ```md-code__content
def find_data_files(file_ext):
"""Find data files in all data files directories.
Args:
file_ext (str): data files with this extension will be listed only
Returns:
(list[str]): list of files
"""
all_datafiles = set()
for app_folder in _list_app_folders():
for appdata_file in os.listdir(app_folder):
file_naming_dict = _match_file(
op.basename(appdata_file)
)
if file_naming_dict \
and file_naming_dict['fname'].endswith(file_ext):
all_datafiles.add(
op.join(app_folder, appdata_file)
)
return all_datafiles
``` | ### `find_instance_data_files(file_ext, instance_id)` Find instance data files in all data files directories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_ext` | `str` | data files with this extension will be listed only | _required_ | | `instance_id` | `int` | list data files for this instance id only | _required_ | Returns: | Type | Description | | --- | --- | | `list[str]` | list of files | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
``` | ```md-code__content
def find_instance_data_files(file_ext, instance_id):
"""Find instance data files in all data files directories.
Args:
file_ext (str): data files with this extension will be listed only
instance_id (int): list data files for this instance id only
Returns:
(list[str]): list of files
"""
# instance files names are like pyRevit_2018_14422_
instance_files = set()
for appdata_file in find_data_files(file_ext):
file_naming_dict = _match_file(
op.basename(appdata_file)
)
if 'pid' in file_naming_dict:
try:
pid = int(file_naming_dict['pid'])
if instance_id == pid:
instance_files.add(appdata_file)
except Exception:
pass
return instance_files
``` | ### `garbage_data_file(file_path)` Mark and remove the given appdata file. Current implementation removes the file immediately. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `file_path` | `str` | path to the target file | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
310
311
312
313
314
315
316
317
318
``` | ```md-code__content
def garbage_data_file(file_path):
"""Mark and remove the given appdata file.
Current implementation removes the file immediately.
Args:
file_path (str): path to the target file
"""
_remove_app_file(file_path)
``` | ### `cleanup_appdata_folder()` Cleanup appdata folder of all temporary appdata files. Source code in `pyrevitlib/pyrevit/coreutils/appdata.py` | | | | --- | --- | | ```
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def cleanup_appdata_folder():
"""Cleanup appdata folder of all temporary appdata files."""
if EXEC_PARAMS.first_load:
hostapp_pids = \
[x.ProcessId
for x in TargetApps.Revit.RevitController.ListRunningRevits()]
for appdata_file in os.listdir(pyrevit.PYREVIT_VERSION_APP_DIR):
file_naming_dict = _match_file(appdata_file)
if 'pid' in file_naming_dict:
try:
pid = int(file_naming_dict['pid'])
if pid not in hostapp_pids:
_remove_app_file(
op.join(pyrevit.PYREVIT_VERSION_APP_DIR,
appdata_file)
)
except Exception:
pass
``` | Back to top ## Bounding Box File Operations [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/bbx/#pyrevit.interop.bbx) # bbx Read and Write Bounding Box Files. ## Functions ### `load(inputfile)` Read list of bounding boxes from file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `inputfile` | `str` | path to input file | _required_ | Returns: | Type | Description | | --- | --- | | `list[tuple[tuple[float, float, float], tuple[float, float, float]]]` | bounding boxes | Source code in `pyrevitlib/pyrevit/interop/bbx.py` | | | | --- | --- | | ```
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
``` | ```md-code__content
def load(inputfile):
"""Read list of bounding boxes from file.
Args:
inputfile (str): path to input file
Returns:
(list[tuple[tuple[float, float, float], tuple[float, float, float]]]):
bounding boxes
"""
bboxes = []
with open(inputfile, 'r') as bbxfile:
# bbox_count = int(bbxfile.readline()) #noqa
for line in bbxfile:
data = line.split(' ')
bboxes.append(
((float(data[0]), float(data[1]), float(data[2])),
(float(data[3]), float(data[4]), float(data[5])))
)
return bboxes
``` | ### `dump(outputfile, bbox_list)` Write list of bounding boxes to file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `outputfile` | `str` | path to output file | _required_ | | `bbox_list` | `list[tuple[tuple[float, float, float], tuple[float, float, float]]]` | bounding boxes | _required_ | Source code in `pyrevitlib/pyrevit/interop/bbx.py` | | | | --- | --- | | ```
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
``` | ```md-code__content
def dump(outputfile, bbox_list):
"""Write list of bounding boxes to file.
Args:
outputfile (str): path to output file
bbox_list (list[tuple[tuple[float, float, float], tuple[float, float, float]]]):
bounding boxes
"""
bbox_count = len(bbox_list)
with open(outputfile, 'w') as bbxfile:
bbxfile.write(str(bbox_count) + '\n')
for bbox in bbox_list:
minx, miny, minz = bbox[0]
maxx, maxy, maxz = bbox[1]
bbxfile.write(
'{:.02f} {:.02f} {:.02f} {:.02f} {:.02f} {:.02f}\n'
.format(minx, miny, minz, maxx, maxy, maxz)
)
``` | Back to top ## Toast Notification Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/forms/toaster/#pyrevit.forms.toaster) # toaster Base module for pushing toast messages on Win 10. This module is a wrapper for a cli utility that provides toast message functionality. See `https://github.com/go-toast/toast` ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Functions ### `get_toaster()` Return full file path of the toast binary utility. Source code in `pyrevitlib/pyrevit/forms/toaster.py` | | | | --- | --- | | ```
18
19
20
``` | ```md-code__content
def get_toaster():
"""Return full file path of the toast binary utility."""
return op.join(op.dirname(__file__), 'pyrevit-toast.exe')
``` | ### `send_toast(message, title=None, appid=None, icon=None, click=None, actions=None)` Send toast notificaton. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | notification message | _required_ | | `title` | `str` | notification title | `None` | | `appid` | `str` | application unique id (see `--app-id` cli option) | `None` | | `icon` | `str` | notification icon (see `--icon` cli option) | `None` | | `click` | `str` | click action (see `--activation-arg` cli option) | `None` | | `actions` | `dict[str` | str\]):
list of actions (see `--action` and `--action-arg` cli options) | `None` | Source code in `pyrevitlib/pyrevit/forms/toaster.py` | | | | --- | --- | | ```
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
``` | ```md-code__content
def send_toast(message,
title=None, appid=None, icon=None, click=None, actions=None):
"""Send toast notificaton.
Args:
message (str): notification message
title (str): notification title
appid (str): application unique id (see `--app-id` cli option)
icon (str): notification icon (see `--icon` cli option)
click (str): click action (see `--activation-arg` cli option)
actions (dict[str:str]):
list of actions (see `--action` and `--action-arg` cli options)
"""
# set defaults
if not title:
title = 'pyRevit'
if not appid:
appid = title
if not icon:
icon = op.join(ROOT_BIN_DIR, 'pyRevit.ico')
if not actions:
actions = {}
# build the toast
toast_args = r'"{}"'.format(get_toaster())
toast_args += r' --app-id "{}"'.format(appid)
toast_args += r' --title "{}"'.format(title)
toast_args += r' --message "{}"'.format(message)
toast_args += r' --icon "{}"'.format(icon)
toast_args += r' --audio "default"'
# toast_args += r' --duration "long"'
if click:
toast_args += r' --activation-arg "{}"'.format(click)
for action, args in actions.items():
toast_args += r' --action "{}" --action-arg "{}"'.format(action, args)
# send the toast now
mlogger.debug('toasting: %s', toast_args)
subprocess.Popen(toast_args, shell=True)
``` | Back to top ## PyRevit System Diagnostics [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/loader/systemdiag/#pyrevit.loader.systemdiag) # systemdiag Session diagnostics. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Functions ### `check_min_host_version()` Source code in `pyrevitlib/pyrevit/loader/systemdiag.py` | | | | --- | --- | | ```
13
14
15
16
17
18
19
``` | ```md-code__content
def check_min_host_version():
# get required version and build from user config
req_build = user_config.required_host_build
if req_build:
if HOST_APP.build != req_build:
mlogger.warning('You are not using the required host build: %s',
req_build)
``` | ### `check_host_drive_freespace()` Source code in `pyrevitlib/pyrevit/loader/systemdiag.py` | | | | --- | --- | | ```
22
23
24
25
26
27
28
29
30
31
32
33
34
``` | ```md-code__content
def check_host_drive_freespace():
# get min free space from user config
min_freespace = user_config.min_host_drivefreespace
if min_freespace:
# find host drive and check free space
host_drive = Path.GetPathRoot(HOST_APP.proc_path)
for drive in DriveInfo.GetDrives():
if drive.Name == host_drive:
free_hd_space = float(drive.TotalFreeSpace) / (1024 ** 3)
if free_hd_space < min_freespace:
mlogger.warning('Remaining space on local drive '
'is less than %sGB...', min_freespace)
``` | ### `system_diag()` Verifies system status is appropriate for a pyRevit session. Source code in `pyrevitlib/pyrevit/loader/systemdiag.py` | | | | --- | --- | | ```
37
38
39
40
41
42
43
``` | ```md-code__content
def system_diag():
"""Verifies system status is appropriate for a pyRevit session."""
# checking available drive space
check_host_drive_freespace()
# check if user is running the required host version and build
check_min_host_version()
``` | Back to top ## Invoke Type Maker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/invoketypemaker/#pyrevit.runtime.invoketypemaker) # invoketypemaker Prepare and compile direct invoke script types. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_executor_type(extension, module_builder, cmd_component)` Source code in `pyrevitlib/pyrevit/runtime/invoketypemaker.py` | | | | --- | --- | | ```
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
``` | ```md-code__content
def create_executor_type(extension, module_builder, cmd_component):
# create argument to pass on to the executor for invoke commands
target_assm_command_class = ''
target_assm = cmd_component.get_target_assembly(required=True)
target_class = cmd_component.command_class
if target_assm and not target_class:
# RevitPythonShell.dll
target_assm_command_class = target_assm
elif target_assm and target_class:
# RevitPythonShell.dll::IronPythonConsoleCommand
target_assm_command_class = '{}::{}'.format(target_assm, target_class)
cmd_component.arguments = [target_assm_command_class]
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
``` | Back to top ## RGB Color Constants [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/colors/#pyrevit.coreutils.colors) # colors Colors constants. Provide RGB color constants and a colors dictionary with elements formatted: COLORS\[colorname\] = CONSTANT. Examples: ```md-code__content from pyrevit.coreutils import colors colors.COLORS['black'] ``` ```md-code__content colors.BLACK ``` ## Attributes ### `ALICEBLUE = RGB(name='aliceblue', red=240, green=248, blue=255)``module-attribute` ### `ANTIQUEWHITE = RGB(name='antiquewhite', red=250, green=235, blue=215)``module-attribute` ### `ANTIQUEWHITE1 = RGB(name='antiquewhite1', red=255, green=239, blue=219)``module-attribute` ### `ANTIQUEWHITE2 = RGB(name='antiquewhite2', red=238, green=223, blue=204)``module-attribute` ### `ANTIQUEWHITE3 = RGB(name='antiquewhite3', red=205, green=192, blue=176)``module-attribute` ### `ANTIQUEWHITE4 = RGB(name='antiquewhite4', red=139, green=131, blue=120)``module-attribute` ### `AQUA = RGB(name='aqua', red=0, green=255, blue=255)``module-attribute` ### `AQUAMARINE1 = RGB(name='aquamarine1', red=127, green=255, blue=212)``module-attribute` ### `AQUAMARINE2 = RGB(name='aquamarine2', red=118, green=238, blue=198)``module-attribute` ### `AQUAMARINE3 = RGB(name='aquamarine3', red=102, green=205, blue=170)``module-attribute` ### `AQUAMARINE4 = RGB(name='aquamarine4', red=69, green=139, blue=116)``module-attribute` ### `AZURE1 = RGB(name='azure1', red=240, green=255, blue=255)``module-attribute` ### `AZURE2 = RGB(name='azure2', red=224, green=238, blue=238)``module-attribute` ### `AZURE3 = RGB(name='azure3', red=193, green=205, blue=205)``module-attribute` ### `AZURE4 = RGB(name='azure4', red=131, green=139, blue=139)``module-attribute` ### `BANANA = RGB(name='banana', red=227, green=207, blue=87)``module-attribute` ### `BEIGE = RGB(name='beige', red=245, green=245, blue=220)``module-attribute` ### `BISQUE1 = RGB(name='bisque1', red=255, green=228, blue=196)``module-attribute` ### `BISQUE2 = RGB(name='bisque2', red=238, green=213, blue=183)``module-attribute` ### `BISQUE3 = RGB(name='bisque3', red=205, green=183, blue=158)``module-attribute` ### `BISQUE4 = RGB(name='bisque4', red=139, green=125, blue=107)``module-attribute` ### `BLACK = RGB(name='black', red=0, green=0, blue=0)``module-attribute` ### `BLANCHEDALMOND = RGB(name='blanchedalmond', red=255, green=235, blue=205)``module-attribute` ### `BLUE = RGB(name='blue', red=0, green=0, blue=255)``module-attribute` ### `BLUE2 = RGB(name='blue2', red=0, green=0, blue=238)``module-attribute` ### `BLUE3 = RGB(name='blue3', red=0, green=0, blue=205)``module-attribute` ### `BLUE4 = RGB(name='blue4', red=0, green=0, blue=139)``module-attribute` ### `BLUEVIOLET = RGB(name='blueviolet', red=138, green=43, blue=226)``module-attribute` ### `BRICK = RGB(name='brick', red=156, green=102, blue=31)``module-attribute` ### `BROWN = RGB(name='brown', red=165, green=42, blue=42)``module-attribute` ### `BROWN1 = RGB(name='brown1', red=255, green=64, blue=64)``module-attribute` ### `BROWN2 = RGB(name='brown2', red=238, green=59, blue=59)``module-attribute` ### `BROWN3 = RGB(name='brown3', red=205, green=51, blue=51)``module-attribute` ### `BROWN4 = RGB(name='brown4', red=139, green=35, blue=35)``module-attribute` ### `BURLYWOOD = RGB(name='burlywood', red=222, green=184, blue=135)``module-attribute` ### `BURLYWOOD1 = RGB(name='burlywood1', red=255, green=211, blue=155)``module-attribute` ### `BURLYWOOD2 = RGB(name='burlywood2', red=238, green=197, blue=145)``module-attribute` ### `BURLYWOOD3 = RGB(name='burlywood3', red=205, green=170, blue=125)``module-attribute` ### `BURLYWOOD4 = RGB(name='burlywood4', red=139, green=115, blue=85)``module-attribute` ### `BURNTSIENNA = RGB(name='burntsienna', red=138, green=54, blue=15)``module-attribute` ### `BURNTUMBER = RGB(name='burntumber', red=138, green=51, blue=36)``module-attribute` ### `CADETBLUE = RGB(name='cadetblue', red=95, green=158, blue=160)``module-attribute` ### `CADETBLUE1 = RGB(name='cadetblue1', red=152, green=245, blue=255)``module-attribute` ### `CADETBLUE2 = RGB(name='cadetblue2', red=142, green=229, blue=238)``module-attribute` ### `CADETBLUE3 = RGB(name='cadetblue3', red=122, green=197, blue=205)``module-attribute` ### `CADETBLUE4 = RGB(name='cadetblue4', red=83, green=134, blue=139)``module-attribute` ### `CADMIUMORANGE = RGB(name='cadmiumorange', red=255, green=97, blue=3)``module-attribute` ### `CADMIUMYELLOW = RGB(name='cadmiumyellow', red=255, green=153, blue=18)``module-attribute` ### `CARROT = RGB(name='carrot', red=237, green=145, blue=33)``module-attribute` ### `CHARTREUSE1 = RGB(name='chartreuse1', red=127, green=255, blue=0)``module-attribute` ### `CHARTREUSE2 = RGB(name='chartreuse2', red=118, green=238, blue=0)``module-attribute` ### `CHARTREUSE3 = RGB(name='chartreuse3', red=102, green=205, blue=0)``module-attribute` ### `CHARTREUSE4 = RGB(name='chartreuse4', red=69, green=139, blue=0)``module-attribute` ### `CHOCOLATE = RGB(name='chocolate', red=210, green=105, blue=30)``module-attribute` ### `CHOCOLATE1 = RGB(name='chocolate1', red=255, green=127, blue=36)``module-attribute` ### `CHOCOLATE2 = RGB(name='chocolate2', red=238, green=118, blue=33)``module-attribute` ### `CHOCOLATE3 = RGB(name='chocolate3', red=205, green=102, blue=29)``module-attribute` ### `CHOCOLATE4 = RGB(name='chocolate4', red=139, green=69, blue=19)``module-attribute` ### `COBALT = RGB(name='cobalt', red=61, green=89, blue=171)``module-attribute` ### `COBALTGREEN = RGB(name='cobaltgreen', red=61, green=145, blue=64)``module-attribute` ### `COLDGREY = RGB(name='coldgrey', red=128, green=138, blue=135)``module-attribute` ### `CORAL = RGB(name='coral', red=255, green=127, blue=80)``module-attribute` ### `CORAL1 = RGB(name='coral1', red=255, green=114, blue=86)``module-attribute` ### `CORAL2 = RGB(name='coral2', red=238, green=106, blue=80)``module-attribute` ### `CORAL3 = RGB(name='coral3', red=205, green=91, blue=69)``module-attribute` ### `CORAL4 = RGB(name='coral4', red=139, green=62, blue=47)``module-attribute` ### `CORNFLOWERBLUE = RGB(name='cornflowerblue', red=100, green=149, blue=237)``module-attribute` ### `CORNSILK1 = RGB(name='cornsilk1', red=255, green=248, blue=220)``module-attribute` ### `CORNSILK2 = RGB(name='cornsilk2', red=238, green=232, blue=205)``module-attribute` ### `CORNSILK3 = RGB(name='cornsilk3', red=205, green=200, blue=177)``module-attribute` ### `CORNSILK4 = RGB(name='cornsilk4', red=139, green=136, blue=120)``module-attribute` ### `CRIMSON = RGB(name='crimson', red=220, green=20, blue=60)``module-attribute` ### `CYAN2 = RGB(name='cyan2', red=0, green=238, blue=238)``module-attribute` ### `CYAN3 = RGB(name='cyan3', red=0, green=205, blue=205)``module-attribute` ### `CYAN4 = RGB(name='cyan4', red=0, green=139, blue=139)``module-attribute` ### `DARKGOLDENROD = RGB(name='darkgoldenrod', red=184, green=134, blue=11)``module-attribute` ### `DARKGOLDENROD1 = RGB(name='darkgoldenrod1', red=255, green=185, blue=15)``module-attribute` ### `DARKGOLDENROD2 = RGB(name='darkgoldenrod2', red=238, green=173, blue=14)``module-attribute` ### `DARKGOLDENROD3 = RGB(name='darkgoldenrod3', red=205, green=149, blue=12)``module-attribute` ### `DARKGOLDENROD4 = RGB(name='darkgoldenrod4', red=139, green=101, blue=8)``module-attribute` ### `DARKGRAY = RGB(name='darkgray', red=169, green=169, blue=169)``module-attribute` ### `DARKGREEN = RGB(name='darkgreen', red=0, green=100, blue=0)``module-attribute` ### `DARKKHAKI = RGB(name='darkkhaki', red=189, green=183, blue=107)``module-attribute` ### `DARKOLIVEGREEN = RGB(name='darkolivegreen', red=85, green=107, blue=47)``module-attribute` ### `DARKOLIVEGREEN1 = RGB(name='darkolivegreen1', red=202, green=255, blue=112)``module-attribute` ### `DARKOLIVEGREEN2 = RGB(name='darkolivegreen2', red=188, green=238, blue=104)``module-attribute` ### `DARKOLIVEGREEN3 = RGB(name='darkolivegreen3', red=162, green=205, blue=90)``module-attribute` ### `DARKOLIVEGREEN4 = RGB(name='darkolivegreen4', red=110, green=139, blue=61)``module-attribute` ### `DARKORANGE = RGB(name='darkorange', red=255, green=140, blue=0)``module-attribute` ### `DARKORANGE1 = RGB(name='darkorange1', red=255, green=127, blue=0)``module-attribute` ### `DARKORANGE2 = RGB(name='darkorange2', red=238, green=118, blue=0)``module-attribute` ### `DARKORANGE3 = RGB(name='darkorange3', red=205, green=102, blue=0)``module-attribute` ### `DARKORANGE4 = RGB(name='darkorange4', red=139, green=69, blue=0)``module-attribute` ### `DARKORCHID = RGB(name='darkorchid', red=153, green=50, blue=204)``module-attribute` ### `DARKORCHID1 = RGB(name='darkorchid1', red=191, green=62, blue=255)``module-attribute` ### `DARKORCHID2 = RGB(name='darkorchid2', red=178, green=58, blue=238)``module-attribute` ### `DARKORCHID3 = RGB(name='darkorchid3', red=154, green=50, blue=205)``module-attribute` ### `DARKORCHID4 = RGB(name='darkorchid4', red=104, green=34, blue=139)``module-attribute` ### `DARKSALMON = RGB(name='darksalmon', red=233, green=150, blue=122)``module-attribute` ### `DARKSEAGREEN = RGB(name='darkseagreen', red=143, green=188, blue=143)``module-attribute` ### `DARKSEAGREEN1 = RGB(name='darkseagreen1', red=193, green=255, blue=193)``module-attribute` ### `DARKSEAGREEN2 = RGB(name='darkseagreen2', red=180, green=238, blue=180)``module-attribute` ### `DARKSEAGREEN3 = RGB(name='darkseagreen3', red=155, green=205, blue=155)``module-attribute` ### `DARKSEAGREEN4 = RGB(name='darkseagreen4', red=105, green=139, blue=105)``module-attribute` ### `DARKSLATEBLUE = RGB(name='darkslateblue', red=72, green=61, blue=139)``module-attribute` ### `DARKSLATEGRAY = RGB(name='darkslategray', red=47, green=79, blue=79)``module-attribute` ### `DARKSLATEGRAY1 = RGB(name='darkslategray1', red=151, green=255, blue=255)``module-attribute` ### `DARKSLATEGRAY2 = RGB(name='darkslategray2', red=141, green=238, blue=238)``module-attribute` ### `DARKSLATEGRAY3 = RGB(name='darkslategray3', red=121, green=205, blue=205)``module-attribute` ### `DARKSLATEGRAY4 = RGB(name='darkslategray4', red=82, green=139, blue=139)``module-attribute` ### `DARKTURQUOISE = RGB(name='darkturquoise', red=0, green=206, blue=209)``module-attribute` ### `DARKVIOLET = RGB(name='darkviolet', red=148, green=0, blue=211)``module-attribute` ### `DEEPPINK1 = RGB(name='deeppink1', red=255, green=20, blue=147)``module-attribute` ### `DEEPPINK2 = RGB(name='deeppink2', red=238, green=18, blue=137)``module-attribute` ### `DEEPPINK3 = RGB(name='deeppink3', red=205, green=16, blue=118)``module-attribute` ### `DEEPPINK4 = RGB(name='deeppink4', red=139, green=10, blue=80)``module-attribute` ### `DEEPSKYBLUE1 = RGB(name='deepskyblue1', red=0, green=191, blue=255)``module-attribute` ### `DEEPSKYBLUE2 = RGB(name='deepskyblue2', red=0, green=178, blue=238)``module-attribute` ### `DEEPSKYBLUE3 = RGB(name='deepskyblue3', red=0, green=154, blue=205)``module-attribute` ### `DEEPSKYBLUE4 = RGB(name='deepskyblue4', red=0, green=104, blue=139)``module-attribute` ### `DIMGRAY = RGB(name='dimgray', red=105, green=105, blue=105)``module-attribute` ### `DODGERBLUE1 = RGB(name='dodgerblue1', red=30, green=144, blue=255)``module-attribute` ### `DODGERBLUE2 = RGB(name='dodgerblue2', red=28, green=134, blue=238)``module-attribute` ### `DODGERBLUE3 = RGB(name='dodgerblue3', red=24, green=116, blue=205)``module-attribute` ### `DODGERBLUE4 = RGB(name='dodgerblue4', red=16, green=78, blue=139)``module-attribute` ### `EGGSHELL = RGB(name='eggshell', red=252, green=230, blue=201)``module-attribute` ### `EMERALDGREEN = RGB(name='emeraldgreen', red=0, green=201, blue=87)``module-attribute` ### `FIREBRICK = RGB(name='firebrick', red=178, green=34, blue=34)``module-attribute` ### `FIREBRICK1 = RGB(name='firebrick1', red=255, green=48, blue=48)``module-attribute` ### `FIREBRICK2 = RGB(name='firebrick2', red=238, green=44, blue=44)``module-attribute` ### `FIREBRICK3 = RGB(name='firebrick3', red=205, green=38, blue=38)``module-attribute` ### `FIREBRICK4 = RGB(name='firebrick4', red=139, green=26, blue=26)``module-attribute` ### `FLESH = RGB(name='flesh', red=255, green=125, blue=64)``module-attribute` ### `FLORALWHITE = RGB(name='floralwhite', red=255, green=250, blue=240)``module-attribute` ### `FORESTGREEN = RGB(name='forestgreen', red=34, green=139, blue=34)``module-attribute` ### `GAINSBORO = RGB(name='gainsboro', red=220, green=220, blue=220)``module-attribute` ### `GHOSTWHITE = RGB(name='ghostwhite', red=248, green=248, blue=255)``module-attribute` ### `GOLD1 = RGB(name='gold1', red=255, green=215, blue=0)``module-attribute` ### `GOLD2 = RGB(name='gold2', red=238, green=201, blue=0)``module-attribute` ### `GOLD3 = RGB(name='gold3', red=205, green=173, blue=0)``module-attribute` ### `GOLD4 = RGB(name='gold4', red=139, green=117, blue=0)``module-attribute` ### `GOLDENROD = RGB(name='goldenrod', red=218, green=165, blue=32)``module-attribute` ### `GOLDENROD1 = RGB(name='goldenrod1', red=255, green=193, blue=37)``module-attribute` ### `GOLDENROD2 = RGB(name='goldenrod2', red=238, green=180, blue=34)``module-attribute` ### `GOLDENROD3 = RGB(name='goldenrod3', red=205, green=155, blue=29)``module-attribute` ### `GOLDENROD4 = RGB(name='goldenrod4', red=139, green=105, blue=20)``module-attribute` ### `GRAY = RGB(name='gray', red=128, green=128, blue=128)``module-attribute` ### `GRAY1 = RGB(name='gray1', red=3, green=3, blue=3)``module-attribute` ### `GRAY10 = RGB(name='gray10', red=26, green=26, blue=26)``module-attribute` ### `GRAY11 = RGB(name='gray11', red=28, green=28, blue=28)``module-attribute` ### `GRAY12 = RGB(name='gray12', red=31, green=31, blue=31)``module-attribute` ### `GRAY13 = RGB(name='gray13', red=33, green=33, blue=33)``module-attribute` ### `GRAY14 = RGB(name='gray14', red=36, green=36, blue=36)``module-attribute` ### `GRAY15 = RGB(name='gray15', red=38, green=38, blue=38)``module-attribute` ### `GRAY16 = RGB(name='gray16', red=41, green=41, blue=41)``module-attribute` ### `GRAY17 = RGB(name='gray17', red=43, green=43, blue=43)``module-attribute` ### `GRAY18 = RGB(name='gray18', red=46, green=46, blue=46)``module-attribute` ### `GRAY19 = RGB(name='gray19', red=48, green=48, blue=48)``module-attribute` ### `GRAY2 = RGB(name='gray2', red=5, green=5, blue=5)``module-attribute` ### `GRAY20 = RGB(name='gray20', red=51, green=51, blue=51)``module-attribute` ### `GRAY21 = RGB(name='gray21', red=54, green=54, blue=54)``module-attribute` ### `GRAY22 = RGB(name='gray22', red=56, green=56, blue=56)``module-attribute` ### `GRAY23 = RGB(name='gray23', red=59, green=59, blue=59)``module-attribute` ### `GRAY24 = RGB(name='gray24', red=61, green=61, blue=61)``module-attribute` ### `GRAY25 = RGB(name='gray25', red=64, green=64, blue=64)``module-attribute` ### `GRAY26 = RGB(name='gray26', red=66, green=66, blue=66)``module-attribute` ### `GRAY27 = RGB(name='gray27', red=69, green=69, blue=69)``module-attribute` ### `GRAY28 = RGB(name='gray28', red=71, green=71, blue=71)``module-attribute` ### `GRAY29 = RGB(name='gray29', red=74, green=74, blue=74)``module-attribute` ### `GRAY3 = RGB(name='gray3', red=8, green=8, blue=8)``module-attribute` ### `GRAY30 = RGB(name='gray30', red=77, green=77, blue=77)``module-attribute` ### `GRAY31 = RGB(name='gray31', red=79, green=79, blue=79)``module-attribute` ### `GRAY32 = RGB(name='gray32', red=82, green=82, blue=82)``module-attribute` ### `GRAY33 = RGB(name='gray33', red=84, green=84, blue=84)``module-attribute` ### `GRAY34 = RGB(name='gray34', red=87, green=87, blue=87)``module-attribute` ### `GRAY35 = RGB(name='gray35', red=89, green=89, blue=89)``module-attribute` ### `GRAY36 = RGB(name='gray36', red=92, green=92, blue=92)``module-attribute` ### `GRAY37 = RGB(name='gray37', red=94, green=94, blue=94)``module-attribute` ### `GRAY38 = RGB(name='gray38', red=97, green=97, blue=97)``module-attribute` ### `GRAY39 = RGB(name='gray39', red=99, green=99, blue=99)``module-attribute` ### `GRAY4 = RGB(name='gray4', red=10, green=10, blue=10)``module-attribute` ### `GRAY40 = RGB(name='gray40', red=102, green=102, blue=102)``module-attribute` ### `GRAY42 = RGB(name='gray42', red=107, green=107, blue=107)``module-attribute` ### `GRAY43 = RGB(name='gray43', red=110, green=110, blue=110)``module-attribute` ### `GRAY44 = RGB(name='gray44', red=112, green=112, blue=112)``module-attribute` ### `GRAY45 = RGB(name='gray45', red=115, green=115, blue=115)``module-attribute` ### `GRAY46 = RGB(name='gray46', red=117, green=117, blue=117)``module-attribute` ### `GRAY47 = RGB(name='gray47', red=120, green=120, blue=120)``module-attribute` ### `GRAY48 = RGB(name='gray48', red=122, green=122, blue=122)``module-attribute` ### `GRAY49 = RGB(name='gray49', red=125, green=125, blue=125)``module-attribute` ### `GRAY5 = RGB(name='gray5', red=13, green=13, blue=13)``module-attribute` ### `GRAY50 = RGB(name='gray50', red=127, green=127, blue=127)``module-attribute` ### `GRAY51 = RGB(name='gray51', red=130, green=130, blue=130)``module-attribute` ### `GRAY52 = RGB(name='gray52', red=133, green=133, blue=133)``module-attribute` ### `GRAY53 = RGB(name='gray53', red=135, green=135, blue=135)``module-attribute` ### `GRAY54 = RGB(name='gray54', red=138, green=138, blue=138)``module-attribute` ### `GRAY55 = RGB(name='gray55', red=140, green=140, blue=140)``module-attribute` ### `GRAY56 = RGB(name='gray56', red=143, green=143, blue=143)``module-attribute` ### `GRAY57 = RGB(name='gray57', red=145, green=145, blue=145)``module-attribute` ### `GRAY58 = RGB(name='gray58', red=148, green=148, blue=148)``module-attribute` ### `GRAY59 = RGB(name='gray59', red=150, green=150, blue=150)``module-attribute` ### `GRAY6 = RGB(name='gray6', red=15, green=15, blue=15)``module-attribute` ### `GRAY60 = RGB(name='gray60', red=153, green=153, blue=153)``module-attribute` ### `GRAY61 = RGB(name='gray61', red=156, green=156, blue=156)``module-attribute` ### `GRAY62 = RGB(name='gray62', red=158, green=158, blue=158)``module-attribute` ### `GRAY63 = RGB(name='gray63', red=161, green=161, blue=161)``module-attribute` ### `GRAY64 = RGB(name='gray64', red=163, green=163, blue=163)``module-attribute` ### `GRAY65 = RGB(name='gray65', red=166, green=166, blue=166)``module-attribute` ### `GRAY66 = RGB(name='gray66', red=168, green=168, blue=168)``module-attribute` ### `GRAY67 = RGB(name='gray67', red=171, green=171, blue=171)``module-attribute` ### `GRAY68 = RGB(name='gray68', red=173, green=173, blue=173)``module-attribute` ### `GRAY69 = RGB(name='gray69', red=176, green=176, blue=176)``module-attribute` ### `GRAY7 = RGB(name='gray7', red=18, green=18, blue=18)``module-attribute` ### `GRAY70 = RGB(name='gray70', red=179, green=179, blue=179)``module-attribute` ### `GRAY71 = RGB(name='gray71', red=181, green=181, blue=181)``module-attribute` ### `GRAY72 = RGB(name='gray72', red=184, green=184, blue=184)``module-attribute` ### `GRAY73 = RGB(name='gray73', red=186, green=186, blue=186)``module-attribute` ### `GRAY74 = RGB(name='gray74', red=189, green=189, blue=189)``module-attribute` ### `GRAY75 = RGB(name='gray75', red=191, green=191, blue=191)``module-attribute` ### `GRAY76 = RGB(name='gray76', red=194, green=194, blue=194)``module-attribute` ### `GRAY77 = RGB(name='gray77', red=196, green=196, blue=196)``module-attribute` ### `GRAY78 = RGB(name='gray78', red=199, green=199, blue=199)``module-attribute` ### `GRAY79 = RGB(name='gray79', red=201, green=201, blue=201)``module-attribute` ### `GRAY8 = RGB(name='gray8', red=20, green=20, blue=20)``module-attribute` ### `GRAY80 = RGB(name='gray80', red=204, green=204, blue=204)``module-attribute` ### `GRAY81 = RGB(name='gray81', red=207, green=207, blue=207)``module-attribute` ### `GRAY82 = RGB(name='gray82', red=209, green=209, blue=209)``module-attribute` ### `GRAY83 = RGB(name='gray83', red=212, green=212, blue=212)``module-attribute` ### `GRAY84 = RGB(name='gray84', red=214, green=214, blue=214)``module-attribute` ### `GRAY85 = RGB(name='gray85', red=217, green=217, blue=217)``module-attribute` ### `GRAY86 = RGB(name='gray86', red=219, green=219, blue=219)``module-attribute` ### `GRAY87 = RGB(name='gray87', red=222, green=222, blue=222)``module-attribute` ### `GRAY88 = RGB(name='gray88', red=224, green=224, blue=224)``module-attribute` ### `GRAY89 = RGB(name='gray89', red=227, green=227, blue=227)``module-attribute` ### `GRAY9 = RGB(name='gray9', red=23, green=23, blue=23)``module-attribute` ### `GRAY90 = RGB(name='gray90', red=229, green=229, blue=229)``module-attribute` ### `GRAY91 = RGB(name='gray91', red=232, green=232, blue=232)``module-attribute` ### `GRAY92 = RGB(name='gray92', red=235, green=235, blue=235)``module-attribute` ### `GRAY93 = RGB(name='gray93', red=237, green=237, blue=237)``module-attribute` ### `GRAY94 = RGB(name='gray94', red=240, green=240, blue=240)``module-attribute` ### `GRAY95 = RGB(name='gray95', red=242, green=242, blue=242)``module-attribute` ### `GRAY97 = RGB(name='gray97', red=247, green=247, blue=247)``module-attribute` ### `GRAY98 = RGB(name='gray98', red=250, green=250, blue=250)``module-attribute` ### `GRAY99 = RGB(name='gray99', red=252, green=252, blue=252)``module-attribute` ### `GREEN = RGB(name='green', red=0, green=128, blue=0)``module-attribute` ### `GREEN1 = RGB(name='green1', red=0, green=255, blue=0)``module-attribute` ### `GREEN2 = RGB(name='green2', red=0, green=238, blue=0)``module-attribute` ### `GREEN3 = RGB(name='green3', red=0, green=205, blue=0)``module-attribute` ### `GREEN4 = RGB(name='green4', red=0, green=139, blue=0)``module-attribute` ### `GREENYELLOW = RGB(name='greenyellow', red=173, green=255, blue=47)``module-attribute` ### `HONEYDEW1 = RGB(name='honeydew1', red=240, green=255, blue=240)``module-attribute` ### `HONEYDEW2 = RGB(name='honeydew2', red=224, green=238, blue=224)``module-attribute` ### `HONEYDEW3 = RGB(name='honeydew3', red=193, green=205, blue=193)``module-attribute` ### `HONEYDEW4 = RGB(name='honeydew4', red=131, green=139, blue=131)``module-attribute` ### `HOTPINK = RGB(name='hotpink', red=255, green=105, blue=180)``module-attribute` ### `HOTPINK1 = RGB(name='hotpink1', red=255, green=110, blue=180)``module-attribute` ### `HOTPINK2 = RGB(name='hotpink2', red=238, green=106, blue=167)``module-attribute` ### `HOTPINK3 = RGB(name='hotpink3', red=205, green=96, blue=144)``module-attribute` ### `HOTPINK4 = RGB(name='hotpink4', red=139, green=58, blue=98)``module-attribute` ### `INDIANRED = RGB(name='indianred', red=205, green=92, blue=92)``module-attribute` ### `INDIANRED1 = RGB(name='indianred1', red=255, green=106, blue=106)``module-attribute` ### `INDIANRED2 = RGB(name='indianred2', red=238, green=99, blue=99)``module-attribute` ### `INDIANRED3 = RGB(name='indianred3', red=205, green=85, blue=85)``module-attribute` ### `INDIANRED4 = RGB(name='indianred4', red=139, green=58, blue=58)``module-attribute` ### `INDIGO = RGB(name='indigo', red=75, green=0, blue=130)``module-attribute` ### `IVORY1 = RGB(name='ivory1', red=255, green=255, blue=240)``module-attribute` ### `IVORY2 = RGB(name='ivory2', red=238, green=238, blue=224)``module-attribute` ### `IVORY3 = RGB(name='ivory3', red=205, green=205, blue=193)``module-attribute` ### `IVORY4 = RGB(name='ivory4', red=139, green=139, blue=131)``module-attribute` ### `IVORYBLACK = RGB(name='ivoryblack', red=41, green=36, blue=33)``module-attribute` ### `KHAKI = RGB(name='khaki', red=240, green=230, blue=140)``module-attribute` ### `KHAKI1 = RGB(name='khaki1', red=255, green=246, blue=143)``module-attribute` ### `KHAKI2 = RGB(name='khaki2', red=238, green=230, blue=133)``module-attribute` ### `KHAKI3 = RGB(name='khaki3', red=205, green=198, blue=115)``module-attribute` ### `KHAKI4 = RGB(name='khaki4', red=139, green=134, blue=78)``module-attribute` ### `LAVENDER = RGB(name='lavender', red=230, green=230, blue=250)``module-attribute` ### `LAVENDERBLUSH1 = RGB(name='lavenderblush1', red=255, green=240, blue=245)``module-attribute` ### `LAVENDERBLUSH2 = RGB(name='lavenderblush2', red=238, green=224, blue=229)``module-attribute` ### `LAVENDERBLUSH3 = RGB(name='lavenderblush3', red=205, green=193, blue=197)``module-attribute` ### `LAVENDERBLUSH4 = RGB(name='lavenderblush4', red=139, green=131, blue=134)``module-attribute` ### `LAWNGREEN = RGB(name='lawngreen', red=124, green=252, blue=0)``module-attribute` ### `LEMONCHIFFON1 = RGB(name='lemonchiffon1', red=255, green=250, blue=205)``module-attribute` ### `LEMONCHIFFON2 = RGB(name='lemonchiffon2', red=238, green=233, blue=191)``module-attribute` ### `LEMONCHIFFON3 = RGB(name='lemonchiffon3', red=205, green=201, blue=165)``module-attribute` ### `LEMONCHIFFON4 = RGB(name='lemonchiffon4', red=139, green=137, blue=112)``module-attribute` ### `LIGHTBLUE = RGB(name='lightblue', red=173, green=216, blue=230)``module-attribute` ### `LIGHTBLUE1 = RGB(name='lightblue1', red=191, green=239, blue=255)``module-attribute` ### `LIGHTBLUE2 = RGB(name='lightblue2', red=178, green=223, blue=238)``module-attribute` ### `LIGHTBLUE3 = RGB(name='lightblue3', red=154, green=192, blue=205)``module-attribute` ### `LIGHTBLUE4 = RGB(name='lightblue4', red=104, green=131, blue=139)``module-attribute` ### `LIGHTCORAL = RGB(name='lightcoral', red=240, green=128, blue=128)``module-attribute` ### `LIGHTCYAN1 = RGB(name='lightcyan1', red=224, green=255, blue=255)``module-attribute` ### `LIGHTCYAN2 = RGB(name='lightcyan2', red=209, green=238, blue=238)``module-attribute` ### `LIGHTCYAN3 = RGB(name='lightcyan3', red=180, green=205, blue=205)``module-attribute` ### `LIGHTCYAN4 = RGB(name='lightcyan4', red=122, green=139, blue=139)``module-attribute` ### `LIGHTGOLDENROD1 = RGB(name='lightgoldenrod1', red=255, green=236, blue=139)``module-attribute` ### `LIGHTGOLDENROD2 = RGB(name='lightgoldenrod2', red=238, green=220, blue=130)``module-attribute` ### `LIGHTGOLDENROD3 = RGB(name='lightgoldenrod3', red=205, green=190, blue=112)``module-attribute` ### `LIGHTGOLDENROD4 = RGB(name='lightgoldenrod4', red=139, green=129, blue=76)``module-attribute` ### `LIGHTGOLDENRODYELLOW = RGB(name='lightgoldenrodyellow', red=250, green=250, blue=210)``module-attribute` ### `LIGHTGREY = RGB(name='lightgrey', red=211, green=211, blue=211)``module-attribute` ### `LIGHTPINK = RGB(name='lightpink', red=255, green=182, blue=193)``module-attribute` ### `LIGHTPINK1 = RGB(name='lightpink1', red=255, green=174, blue=185)``module-attribute` ### `LIGHTPINK2 = RGB(name='lightpink2', red=238, green=162, blue=173)``module-attribute` ### `LIGHTPINK3 = RGB(name='lightpink3', red=205, green=140, blue=149)``module-attribute` ### `LIGHTPINK4 = RGB(name='lightpink4', red=139, green=95, blue=101)``module-attribute` ### `LIGHTSALMON1 = RGB(name='lightsalmon1', red=255, green=160, blue=122)``module-attribute` ### `LIGHTSALMON2 = RGB(name='lightsalmon2', red=238, green=149, blue=114)``module-attribute` ### `LIGHTSALMON3 = RGB(name='lightsalmon3', red=205, green=129, blue=98)``module-attribute` ### `LIGHTSALMON4 = RGB(name='lightsalmon4', red=139, green=87, blue=66)``module-attribute` ### `LIGHTSEAGREEN = RGB(name='lightseagreen', red=32, green=178, blue=170)``module-attribute` ### `LIGHTSKYBLUE = RGB(name='lightskyblue', red=135, green=206, blue=250)``module-attribute` ### `LIGHTSKYBLUE1 = RGB(name='lightskyblue1', red=176, green=226, blue=255)``module-attribute` ### `LIGHTSKYBLUE2 = RGB(name='lightskyblue2', red=164, green=211, blue=238)``module-attribute` ### `LIGHTSKYBLUE3 = RGB(name='lightskyblue3', red=141, green=182, blue=205)``module-attribute` ### `LIGHTSKYBLUE4 = RGB(name='lightskyblue4', red=96, green=123, blue=139)``module-attribute` ### `LIGHTSLATEBLUE = RGB(name='lightslateblue', red=132, green=112, blue=255)``module-attribute` ### `LIGHTSLATEGRAY = RGB(name='lightslategray', red=119, green=136, blue=153)``module-attribute` ### `LIGHTSTEELBLUE = RGB(name='lightsteelblue', red=176, green=196, blue=222)``module-attribute` ### `LIGHTSTEELBLUE1 = RGB(name='lightsteelblue1', red=202, green=225, blue=255)``module-attribute` ### `LIGHTSTEELBLUE2 = RGB(name='lightsteelblue2', red=188, green=210, blue=238)``module-attribute` ### `LIGHTSTEELBLUE3 = RGB(name='lightsteelblue3', red=162, green=181, blue=205)``module-attribute` ### `LIGHTSTEELBLUE4 = RGB(name='lightsteelblue4', red=110, green=123, blue=139)``module-attribute` ### `LIGHTYELLOW1 = RGB(name='lightyellow1', red=255, green=255, blue=224)``module-attribute` ### `LIGHTYELLOW2 = RGB(name='lightyellow2', red=238, green=238, blue=209)``module-attribute` ### `LIGHTYELLOW3 = RGB(name='lightyellow3', red=205, green=205, blue=180)``module-attribute` ### `LIGHTYELLOW4 = RGB(name='lightyellow4', red=139, green=139, blue=122)``module-attribute` ### `LIMEGREEN = RGB(name='limegreen', red=50, green=205, blue=50)``module-attribute` ### `LINEN = RGB(name='linen', red=250, green=240, blue=230)``module-attribute` ### `MAGENTA = RGB(name='magenta', red=255, green=0, blue=255)``module-attribute` ### `MAGENTA2 = RGB(name='magenta2', red=238, green=0, blue=238)``module-attribute` ### `MAGENTA3 = RGB(name='magenta3', red=205, green=0, blue=205)``module-attribute` ### `MAGENTA4 = RGB(name='magenta4', red=139, green=0, blue=139)``module-attribute` ### `MANGANESEBLUE = RGB(name='manganeseblue', red=3, green=168, blue=158)``module-attribute` ### `MAROON = RGB(name='maroon', red=128, green=0, blue=0)``module-attribute` ### `MAROON1 = RGB(name='maroon1', red=255, green=52, blue=179)``module-attribute` ### `MAROON2 = RGB(name='maroon2', red=238, green=48, blue=167)``module-attribute` ### `MAROON3 = RGB(name='maroon3', red=205, green=41, blue=144)``module-attribute` ### `MAROON4 = RGB(name='maroon4', red=139, green=28, blue=98)``module-attribute` ### `MEDIUMORCHID = RGB(name='mediumorchid', red=186, green=85, blue=211)``module-attribute` ### `MEDIUMORCHID1 = RGB(name='mediumorchid1', red=224, green=102, blue=255)``module-attribute` ### `MEDIUMORCHID2 = RGB(name='mediumorchid2', red=209, green=95, blue=238)``module-attribute` ### `MEDIUMORCHID3 = RGB(name='mediumorchid3', red=180, green=82, blue=205)``module-attribute` ### `MEDIUMORCHID4 = RGB(name='mediumorchid4', red=122, green=55, blue=139)``module-attribute` ### `MEDIUMPURPLE = RGB(name='mediumpurple', red=147, green=112, blue=219)``module-attribute` ### `MEDIUMPURPLE1 = RGB(name='mediumpurple1', red=171, green=130, blue=255)``module-attribute` ### `MEDIUMPURPLE2 = RGB(name='mediumpurple2', red=159, green=121, blue=238)``module-attribute` ### `MEDIUMPURPLE3 = RGB(name='mediumpurple3', red=137, green=104, blue=205)``module-attribute` ### `MEDIUMPURPLE4 = RGB(name='mediumpurple4', red=93, green=71, blue=139)``module-attribute` ### `MEDIUMSEAGREEN = RGB(name='mediumseagreen', red=60, green=179, blue=113)``module-attribute` ### `MEDIUMSLATEBLUE = RGB(name='mediumslateblue', red=123, green=104, blue=238)``module-attribute` ### `MEDIUMSPRINGGREEN = RGB(name='mediumspringgreen', red=0, green=250, blue=154)``module-attribute` ### `MEDIUMTURQUOISE = RGB(name='mediumturquoise', red=72, green=209, blue=204)``module-attribute` ### `MEDIUMVIOLETRED = RGB(name='mediumvioletred', red=199, green=21, blue=133)``module-attribute` ### `MELON = RGB(name='melon', red=227, green=168, blue=105)``module-attribute` ### `MIDNIGHTBLUE = RGB(name='midnightblue', red=25, green=25, blue=112)``module-attribute` ### `MINT = RGB(name='mint', red=189, green=252, blue=201)``module-attribute` ### `MINTCREAM = RGB(name='mintcream', red=245, green=255, blue=250)``module-attribute` ### `MISTYROSE1 = RGB(name='mistyrose1', red=255, green=228, blue=225)``module-attribute` ### `MISTYROSE2 = RGB(name='mistyrose2', red=238, green=213, blue=210)``module-attribute` ### `MISTYROSE3 = RGB(name='mistyrose3', red=205, green=183, blue=181)``module-attribute` ### `MISTYROSE4 = RGB(name='mistyrose4', red=139, green=125, blue=123)``module-attribute` ### `MOCCASIN = RGB(name='moccasin', red=255, green=228, blue=181)``module-attribute` ### `NAVAJOWHITE1 = RGB(name='navajowhite1', red=255, green=222, blue=173)``module-attribute` ### `NAVAJOWHITE2 = RGB(name='navajowhite2', red=238, green=207, blue=161)``module-attribute` ### `NAVAJOWHITE3 = RGB(name='navajowhite3', red=205, green=179, blue=139)``module-attribute` ### `NAVAJOWHITE4 = RGB(name='navajowhite4', red=139, green=121, blue=94)``module-attribute` ### `NAVY = RGB(name='navy', red=0, green=0, blue=128)``module-attribute` ### `OLDLACE = RGB(name='oldlace', red=253, green=245, blue=230)``module-attribute` ### `OLIVE = RGB(name='olive', red=128, green=128, blue=0)``module-attribute` ### `OLIVEDRAB = RGB(name='olivedrab', red=107, green=142, blue=35)``module-attribute` ### `OLIVEDRAB1 = RGB(name='olivedrab1', red=192, green=255, blue=62)``module-attribute` ### `OLIVEDRAB2 = RGB(name='olivedrab2', red=179, green=238, blue=58)``module-attribute` ### `OLIVEDRAB3 = RGB(name='olivedrab3', red=154, green=205, blue=50)``module-attribute` ### `OLIVEDRAB4 = RGB(name='olivedrab4', red=105, green=139, blue=34)``module-attribute` ### `ORANGE = RGB(name='orange', red=255, green=128, blue=0)``module-attribute` ### `ORANGE1 = RGB(name='orange1', red=255, green=165, blue=0)``module-attribute` ### `ORANGE2 = RGB(name='orange2', red=238, green=154, blue=0)``module-attribute` ### `ORANGE3 = RGB(name='orange3', red=205, green=133, blue=0)``module-attribute` ### `ORANGE4 = RGB(name='orange4', red=139, green=90, blue=0)``module-attribute` ### `ORANGERED1 = RGB(name='orangered1', red=255, green=69, blue=0)``module-attribute` ### `ORANGERED2 = RGB(name='orangered2', red=238, green=64, blue=0)``module-attribute` ### `ORANGERED3 = RGB(name='orangered3', red=205, green=55, blue=0)``module-attribute` ### `ORANGERED4 = RGB(name='orangered4', red=139, green=37, blue=0)``module-attribute` ### `ORCHID = RGB(name='orchid', red=218, green=112, blue=214)``module-attribute` ### `ORCHID1 = RGB(name='orchid1', red=255, green=131, blue=250)``module-attribute` ### `ORCHID2 = RGB(name='orchid2', red=238, green=122, blue=233)``module-attribute` ### `ORCHID3 = RGB(name='orchid3', red=205, green=105, blue=201)``module-attribute` ### `ORCHID4 = RGB(name='orchid4', red=139, green=71, blue=137)``module-attribute` ### `PALEGOLDENROD = RGB(name='palegoldenrod', red=238, green=232, blue=170)``module-attribute` ### `PALEGREEN = RGB(name='palegreen', red=152, green=251, blue=152)``module-attribute` ### `PALEGREEN1 = RGB(name='palegreen1', red=154, green=255, blue=154)``module-attribute` ### `PALEGREEN2 = RGB(name='palegreen2', red=144, green=238, blue=144)``module-attribute` ### `PALEGREEN3 = RGB(name='palegreen3', red=124, green=205, blue=124)``module-attribute` ### `PALEGREEN4 = RGB(name='palegreen4', red=84, green=139, blue=84)``module-attribute` ### `PALETURQUOISE1 = RGB(name='paleturquoise1', red=187, green=255, blue=255)``module-attribute` ### `PALETURQUOISE2 = RGB(name='paleturquoise2', red=174, green=238, blue=238)``module-attribute` ### `PALETURQUOISE3 = RGB(name='paleturquoise3', red=150, green=205, blue=205)``module-attribute` ### `PALETURQUOISE4 = RGB(name='paleturquoise4', red=102, green=139, blue=139)``module-attribute` ### `PALEVIOLETRED = RGB(name='palevioletred', red=219, green=112, blue=147)``module-attribute` ### `PALEVIOLETRED1 = RGB(name='palevioletred1', red=255, green=130, blue=171)``module-attribute` ### `PALEVIOLETRED2 = RGB(name='palevioletred2', red=238, green=121, blue=159)``module-attribute` ### `PALEVIOLETRED3 = RGB(name='palevioletred3', red=205, green=104, blue=137)``module-attribute` ### `PALEVIOLETRED4 = RGB(name='palevioletred4', red=139, green=71, blue=93)``module-attribute` ### `PAPAYAWHIP = RGB(name='papayawhip', red=255, green=239, blue=213)``module-attribute` ### `PEACHPUFF1 = RGB(name='peachpuff1', red=255, green=218, blue=185)``module-attribute` ### `PEACHPUFF2 = RGB(name='peachpuff2', red=238, green=203, blue=173)``module-attribute` ### `PEACHPUFF3 = RGB(name='peachpuff3', red=205, green=175, blue=149)``module-attribute` ### `PEACHPUFF4 = RGB(name='peachpuff4', red=139, green=119, blue=101)``module-attribute` ### `PEACOCK = RGB(name='peacock', red=51, green=161, blue=201)``module-attribute` ### `PINK = RGB(name='pink', red=255, green=192, blue=203)``module-attribute` ### `PINK1 = RGB(name='pink1', red=255, green=181, blue=197)``module-attribute` ### `PINK2 = RGB(name='pink2', red=238, green=169, blue=184)``module-attribute` ### `PINK3 = RGB(name='pink3', red=205, green=145, blue=158)``module-attribute` ### `PINK4 = RGB(name='pink4', red=139, green=99, blue=108)``module-attribute` ### `PLUM = RGB(name='plum', red=221, green=160, blue=221)``module-attribute` ### `PLUM1 = RGB(name='plum1', red=255, green=187, blue=255)``module-attribute` ### `PLUM2 = RGB(name='plum2', red=238, green=174, blue=238)``module-attribute` ### `PLUM3 = RGB(name='plum3', red=205, green=150, blue=205)``module-attribute` ### `PLUM4 = RGB(name='plum4', red=139, green=102, blue=139)``module-attribute` ### `POWDERBLUE = RGB(name='powderblue', red=176, green=224, blue=230)``module-attribute` ### `PURPLE = RGB(name='purple', red=128, green=0, blue=128)``module-attribute` ### `PURPLE1 = RGB(name='purple1', red=155, green=48, blue=255)``module-attribute` ### `PURPLE2 = RGB(name='purple2', red=145, green=44, blue=238)``module-attribute` ### `PURPLE3 = RGB(name='purple3', red=125, green=38, blue=205)``module-attribute` ### `PURPLE4 = RGB(name='purple4', red=85, green=26, blue=139)``module-attribute` ### `RASPBERRY = RGB(name='raspberry', red=135, green=38, blue=87)``module-attribute` ### `RAWSIENNA = RGB(name='rawsienna', red=199, green=97, blue=20)``module-attribute` ### `RED1 = RGB(name='red1', red=255, green=0, blue=0)``module-attribute` ### `RED2 = RGB(name='red2', red=238, green=0, blue=0)``module-attribute` ### `RED3 = RGB(name='red3', red=205, green=0, blue=0)``module-attribute` ### `RED4 = RGB(name='red4', red=139, green=0, blue=0)``module-attribute` ### `ROSYBROWN = RGB(name='rosybrown', red=188, green=143, blue=143)``module-attribute` ### `ROSYBROWN1 = RGB(name='rosybrown1', red=255, green=193, blue=193)``module-attribute` ### `ROSYBROWN2 = RGB(name='rosybrown2', red=238, green=180, blue=180)``module-attribute` ### `ROSYBROWN3 = RGB(name='rosybrown3', red=205, green=155, blue=155)``module-attribute` ### `ROSYBROWN4 = RGB(name='rosybrown4', red=139, green=105, blue=105)``module-attribute` ### `ROYALBLUE = RGB(name='royalblue', red=65, green=105, blue=225)``module-attribute` ### `ROYALBLUE1 = RGB(name='royalblue1', red=72, green=118, blue=255)``module-attribute` ### `ROYALBLUE2 = RGB(name='royalblue2', red=67, green=110, blue=238)``module-attribute` ### `ROYALBLUE3 = RGB(name='royalblue3', red=58, green=95, blue=205)``module-attribute` ### `ROYALBLUE4 = RGB(name='royalblue4', red=39, green=64, blue=139)``module-attribute` ### `SALMON = RGB(name='salmon', red=250, green=128, blue=114)``module-attribute` ### `SALMON1 = RGB(name='salmon1', red=255, green=140, blue=105)``module-attribute` ### `SALMON2 = RGB(name='salmon2', red=238, green=130, blue=98)``module-attribute` ### `SALMON3 = RGB(name='salmon3', red=205, green=112, blue=84)``module-attribute` ### `SALMON4 = RGB(name='salmon4', red=139, green=76, blue=57)``module-attribute` ### `SANDYBROWN = RGB(name='sandybrown', red=244, green=164, blue=96)``module-attribute` ### `SAPGREEN = RGB(name='sapgreen', red=48, green=128, blue=20)``module-attribute` ### `SEAGREEN1 = RGB(name='seagreen1', red=84, green=255, blue=159)``module-attribute` ### `SEAGREEN2 = RGB(name='seagreen2', red=78, green=238, blue=148)``module-attribute` ### `SEAGREEN3 = RGB(name='seagreen3', red=67, green=205, blue=128)``module-attribute` ### `SEAGREEN4 = RGB(name='seagreen4', red=46, green=139, blue=87)``module-attribute` ### `SEASHELL1 = RGB(name='seashell1', red=255, green=245, blue=238)``module-attribute` ### `SEASHELL2 = RGB(name='seashell2', red=238, green=229, blue=222)``module-attribute` ### `SEASHELL3 = RGB(name='seashell3', red=205, green=197, blue=191)``module-attribute` ### `SEASHELL4 = RGB(name='seashell4', red=139, green=134, blue=130)``module-attribute` ### `SEPIA = RGB(name='sepia', red=94, green=38, blue=18)``module-attribute` ### `SGIBEET = RGB(name='sgibeet', red=142, green=56, blue=142)``module-attribute` ### `SGIBRIGHTGRAY = RGB(name='sgibrightgray', red=197, green=193, blue=170)``module-attribute` ### `SGICHARTREUSE = RGB(name='sgichartreuse', red=113, green=198, blue=113)``module-attribute` ### `SGIDARKGRAY = RGB(name='sgidarkgray', red=85, green=85, blue=85)``module-attribute` ### `SGIGRAY12 = RGB(name='sgigray12', red=30, green=30, blue=30)``module-attribute` ### `SGIGRAY16 = RGB(name='sgigray16', red=40, green=40, blue=40)``module-attribute` ### `SGIGRAY32 = RGB(name='sgigray32', red=81, green=81, blue=81)``module-attribute` ### `SGIGRAY36 = RGB(name='sgigray36', red=91, green=91, blue=91)``module-attribute` ### `SGIGRAY52 = RGB(name='sgigray52', red=132, green=132, blue=132)``module-attribute` ### `SGIGRAY56 = RGB(name='sgigray56', red=142, green=142, blue=142)``module-attribute` ### `SGIGRAY72 = RGB(name='sgigray72', red=183, green=183, blue=183)``module-attribute` ### `SGIGRAY76 = RGB(name='sgigray76', red=193, green=193, blue=193)``module-attribute` ### `SGIGRAY92 = RGB(name='sgigray92', red=234, green=234, blue=234)``module-attribute` ### `SGIGRAY96 = RGB(name='sgigray96', red=244, green=244, blue=244)``module-attribute` ### `SGILIGHTBLUE = RGB(name='sgilightblue', red=125, green=158, blue=192)``module-attribute` ### `SGILIGHTGRAY = RGB(name='sgilightgray', red=170, green=170, blue=170)``module-attribute` ### `SGIOLIVEDRAB = RGB(name='sgiolivedrab', red=142, green=142, blue=56)``module-attribute` ### `SGISALMON = RGB(name='sgisalmon', red=198, green=113, blue=113)``module-attribute` ### `SGISLATEBLUE = RGB(name='sgislateblue', red=113, green=113, blue=198)``module-attribute` ### `SGITEAL = RGB(name='sgiteal', red=56, green=142, blue=142)``module-attribute` ### `SIENNA = RGB(name='sienna', red=160, green=82, blue=45)``module-attribute` ### `SIENNA1 = RGB(name='sienna1', red=255, green=130, blue=71)``module-attribute` ### `SIENNA2 = RGB(name='sienna2', red=238, green=121, blue=66)``module-attribute` ### `SIENNA3 = RGB(name='sienna3', red=205, green=104, blue=57)``module-attribute` ### `SIENNA4 = RGB(name='sienna4', red=139, green=71, blue=38)``module-attribute` ### `SILVER = RGB(name='silver', red=192, green=192, blue=192)``module-attribute` ### `SKYBLUE = RGB(name='skyblue', red=135, green=206, blue=235)``module-attribute` ### `SKYBLUE1 = RGB(name='skyblue1', red=135, green=206, blue=255)``module-attribute` ### `SKYBLUE2 = RGB(name='skyblue2', red=126, green=192, blue=238)``module-attribute` ### `SKYBLUE3 = RGB(name='skyblue3', red=108, green=166, blue=205)``module-attribute` ### `SKYBLUE4 = RGB(name='skyblue4', red=74, green=112, blue=139)``module-attribute` ### `SLATEBLUE = RGB(name='slateblue', red=106, green=90, blue=205)``module-attribute` ### `SLATEBLUE1 = RGB(name='slateblue1', red=131, green=111, blue=255)``module-attribute` ### `SLATEBLUE2 = RGB(name='slateblue2', red=122, green=103, blue=238)``module-attribute` ### `SLATEBLUE3 = RGB(name='slateblue3', red=105, green=89, blue=205)``module-attribute` ### `SLATEBLUE4 = RGB(name='slateblue4', red=71, green=60, blue=139)``module-attribute` ### `SLATEGRAY = RGB(name='slategray', red=112, green=128, blue=144)``module-attribute` ### `SLATEGRAY1 = RGB(name='slategray1', red=198, green=226, blue=255)``module-attribute` ### `SLATEGRAY2 = RGB(name='slategray2', red=185, green=211, blue=238)``module-attribute` ### `SLATEGRAY3 = RGB(name='slategray3', red=159, green=182, blue=205)``module-attribute` ### `SLATEGRAY4 = RGB(name='slategray4', red=108, green=123, blue=139)``module-attribute` ### `SNOW1 = RGB(name='snow1', red=255, green=250, blue=250)``module-attribute` ### `SNOW2 = RGB(name='snow2', red=238, green=233, blue=233)``module-attribute` ### `SNOW3 = RGB(name='snow3', red=205, green=201, blue=201)``module-attribute` ### `SNOW4 = RGB(name='snow4', red=139, green=137, blue=137)``module-attribute` ### `SPRINGGREEN = RGB(name='springgreen', red=0, green=255, blue=127)``module-attribute` ### `SPRINGGREEN1 = RGB(name='springgreen1', red=0, green=238, blue=118)``module-attribute` ### `SPRINGGREEN2 = RGB(name='springgreen2', red=0, green=205, blue=102)``module-attribute` ### `SPRINGGREEN3 = RGB(name='springgreen3', red=0, green=139, blue=69)``module-attribute` ### `STEELBLUE = RGB(name='steelblue', red=70, green=130, blue=180)``module-attribute` ### `STEELBLUE1 = RGB(name='steelblue1', red=99, green=184, blue=255)``module-attribute` ### `STEELBLUE2 = RGB(name='steelblue2', red=92, green=172, blue=238)``module-attribute` ### `STEELBLUE3 = RGB(name='steelblue3', red=79, green=148, blue=205)``module-attribute` ### `STEELBLUE4 = RGB(name='steelblue4', red=54, green=100, blue=139)``module-attribute` ### `TAN = RGB(name='tan', red=210, green=180, blue=140)``module-attribute` ### `TAN1 = RGB(name='tan1', red=255, green=165, blue=79)``module-attribute` ### `TAN2 = RGB(name='tan2', red=238, green=154, blue=73)``module-attribute` ### `TAN3 = RGB(name='tan3', red=205, green=133, blue=63)``module-attribute` ### `TAN4 = RGB(name='tan4', red=139, green=90, blue=43)``module-attribute` ### `TEAL = RGB(name='teal', red=0, green=128, blue=128)``module-attribute` ### `THISTLE = RGB(name='thistle', red=216, green=191, blue=216)``module-attribute` ### `THISTLE1 = RGB(name='thistle1', red=255, green=225, blue=255)``module-attribute` ### `THISTLE2 = RGB(name='thistle2', red=238, green=210, blue=238)``module-attribute` ### `THISTLE3 = RGB(name='thistle3', red=205, green=181, blue=205)``module-attribute` ### `THISTLE4 = RGB(name='thistle4', red=139, green=123, blue=139)``module-attribute` ### `TOMATO1 = RGB(name='tomato1', red=255, green=99, blue=71)``module-attribute` ### `TOMATO2 = RGB(name='tomato2', red=238, green=92, blue=66)``module-attribute` ### `TOMATO3 = RGB(name='tomato3', red=205, green=79, blue=57)``module-attribute` ### `TOMATO4 = RGB(name='tomato4', red=139, green=54, blue=38)``module-attribute` ### `TURQUOISE = RGB(name='turquoise', red=64, green=224, blue=208)``module-attribute` ### `TURQUOISE1 = RGB(name='turquoise1', red=0, green=245, blue=255)``module-attribute` ### `TURQUOISE2 = RGB(name='turquoise2', red=0, green=229, blue=238)``module-attribute` ### `TURQUOISE3 = RGB(name='turquoise3', red=0, green=197, blue=205)``module-attribute` ### `TURQUOISE4 = RGB(name='turquoise4', red=0, green=134, blue=139)``module-attribute` ### `TURQUOISEBLUE = RGB(name='turquoiseblue', red=0, green=199, blue=140)``module-attribute` ### `VIOLET = RGB(name='violet', red=238, green=130, blue=238)``module-attribute` ### `VIOLETRED = RGB(name='violetred', red=208, green=32, blue=144)``module-attribute` ### `VIOLETRED1 = RGB(name='violetred1', red=255, green=62, blue=150)``module-attribute` ### `VIOLETRED2 = RGB(name='violetred2', red=238, green=58, blue=140)``module-attribute` ### `VIOLETRED3 = RGB(name='violetred3', red=205, green=50, blue=120)``module-attribute` ### `VIOLETRED4 = RGB(name='violetred4', red=139, green=34, blue=82)``module-attribute` ### `WARMGREY = RGB(name='warmgrey', red=128, green=128, blue=105)``module-attribute` ### `WHEAT = RGB(name='wheat', red=245, green=222, blue=179)``module-attribute` ### `WHEAT1 = RGB(name='wheat1', red=255, green=231, blue=186)``module-attribute` ### `WHEAT2 = RGB(name='wheat2', red=238, green=216, blue=174)``module-attribute` ### `WHEAT3 = RGB(name='wheat3', red=205, green=186, blue=150)``module-attribute` ### `WHEAT4 = RGB(name='wheat4', red=139, green=126, blue=102)``module-attribute` ### `WHITE = RGB(name='white', red=255, green=255, blue=255)``module-attribute` ### `WHITESMOKE = RGB(name='whitesmoke', red=245, green=245, blue=245)``module-attribute` ### `YELLOW1 = RGB(name='yellow1', red=255, green=255, blue=0)``module-attribute` ### `YELLOW2 = RGB(name='yellow2', red=238, green=238, blue=0)``module-attribute` ### `YELLOW3 = RGB(name='yellow3', red=205, green=205, blue=0)``module-attribute` ### `YELLOW4 = RGB(name='yellow4', red=139, green=139, blue=0)``module-attribute` ### `COLORS = OrderedDict(sorted(COLORS.items(), key=lambda t: t[0]))``module-attribute` ## Classes ### `RGB(name='default', red=0, green=0, blue=0)` Bases: `object` RGB named color object. Attributes: | Name | Type | Description | | --- | --- | --- | | `name` | `str` | color name | | `red` | `int` | value for red component (0-255) | | `green` | `int` | value for green component (0-255) | | `blue` | `int` | value for blue component (0-255) | Source code in `pyrevitlib/pyrevit/coreutils/colors.py` | | | | --- | --- | | ```
31
32
33
``` | ```md-code__content
def __init__(self, name='default', red=0, green=0, blue=0):
self.name = name
self.red, self.green, self.blue = red, green, blue
``` | #### Attributes ##### `name = name``instance-attribute` ##### `hex_color``property` Return color in hex format. ##### `luminance``property` Return color luminance (preceived). ##### `safe_text_color``property` Return text color that is safe to overlap this color. Back to top ## pyRevit Updater [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/versionmgr/updater/#pyrevit.versionmgr.updater) # updater Handle updating pyRevit repository and its extensions. ## Attributes ### `logger = get_logger(__name__)``module-attribute` ### `COREUPDATE_TRIGGER = 'COREUPDATE'``module-attribute` ### `COREUPDATE_MESSAGE = '
IMPORTANT\npyRevit has a major core update. This update can not be applied when Revit is running. Please close all Revit instances, and update the clone using the pyRevit CLI. Start Revit again after the update and pyRevit will load with the new core changes.
'``module-attribute` ## Functions ### `get_thirdparty_ext_repos()` Return a list of repos for installed third-party extensions. Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
``` | ```md-code__content
def get_thirdparty_ext_repos():
"""Return a list of repos for installed third-party extensions."""
processed_paths = set()
valid_exts = []
ext_repos = []
logger.debug('Finding installed repos...')
ext_info_list = extensionmgr.get_thirdparty_extension_data()
for ext_info in ext_info_list:
repo_path = libgit.libgit.Repository.Discover(ext_info.directory)
if repo_path:
repo_info = libgit.get_repo(repo_path)
if repo_info:
valid_exts.append(ext_info)
if repo_info.directory not in processed_paths:
processed_paths.add(repo_info.directory)
ext_repos.append(repo_info)
logger.debug('Valid third-party extensions for update: %s', valid_exts)
return ext_repos
``` | ### `get_all_extension_repos()` Return a list of repos for all installed extensions. Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
87
88
89
90
91
92
93
94
95
96
97
98
``` | ```md-code__content
def get_all_extension_repos():
"""Return a list of repos for all installed extensions."""
logger.debug('Finding all extension repos.')
# pyrevit main repo
repo_info_list = []
pyrevit_repo = versionmgr.get_pyrevit_repo()
if pyrevit_repo:
repo_info_list.append(pyrevit_repo)
# add all thirdparty extension repos
repo_info_list.extend(get_thirdparty_ext_repos())
logger.debug('Repos are: %s', repo_info_list)
return repo_info_list
``` | ### `update_repo(repo_info)` Update repository. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | | obj: `pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object | _required_ | Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
``` | ```md-code__content
def update_repo(repo_info):
"""Update repository.
Args:
repo_info (:obj:`pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object
"""
repo = repo_info.repo
logger.debug('Updating repo: %s', repo_info.directory)
head_msg = safe_strtype(repo.Head.Tip.Message).replace('\n', '')
logger.debug('Current head is: %s > %s', repo.Head.Tip.Id.Sha, head_msg)
username, password = _get_extension_credentials(repo_info)
if username and password:
repo_info.username = username
repo_info.password = password
try:
updated_repo_info = libgit.git_pull(repo_info)
logger.debug('Successfully updated repo: %s',
updated_repo_info.directory)
return updated_repo_info
except libgit.PyRevitGitAuthenticationError as auth_err:
logger.debug('Can not login to git repository to get updates: %s | %s',
repo_info, auth_err)
raise auth_err
except Exception as update_err:
logger.debug('Failed updating repo: %s | %s', repo_info, update_err)
raise update_err
``` | ### `get_updates(repo_info)` Fetch updates on repository. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | | obj: `pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object | _required_ | Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
``` | ```md-code__content
def get_updates(repo_info):
"""Fetch updates on repository.
Args:
repo_info (:obj:`pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object
"""
repo = repo_info.repo
at_least_one_fetch_was_successful = False
logger.debug('Fetching updates for: %s', repo_info.directory)
for remote in repo.Network.Remotes:
try:
_fetch_remote(remote, repo_info)
at_least_one_fetch_was_successful = True
except libgit.PyRevitGitAuthenticationError:
logger.debug('Failed fetching updates. '
'Can not login to repo to get updates: %s', repo_info)
continue
except Exception:
logger.debug('Failed fetching updates: %s', repo_info)
continue
if at_least_one_fetch_was_successful:
return True
return False
``` | ### `has_pending_updates(repo_info)` Check for updates on repository. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `repo_info` | | obj: `pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object | _required_ | Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
164
165
166
167
168
169
170
171
172
173
174
``` | ```md-code__content
def has_pending_updates(repo_info):
"""Check for updates on repository.
Args:
repo_info (:obj:`pyrevit.coreutils.git.RepoInfo`):
repository info wrapper object
"""
if get_updates(repo_info):
hist_div = libgit.compare_branch_heads(repo_info)
if hist_div.BehindBy > 0:
return True
``` | ### `check_for_updates()` Check whether any available repo has pending updates. Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
``` | ```md-code__content
def check_for_updates():
"""Check whether any available repo has pending updates."""
if _check_connection():
logger.info('Checking for updates...')
for repo in get_all_extension_repos():
if has_pending_updates(repo):
logger.info('Updates are available for %s...', repo.name)
return True
else:
logger.info('%s is up-to-date...', repo.name)
else:
logger.warning('No internet access detected. '
'Skipping check for updates.')
return False
``` | ### `has_core_updates()` Check whether pyRevit repo has core updates. This would require host application to be closed to release the file lock of core DLLs so they can be updated separately. Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
``` | ```md-code__content
def has_core_updates():
"""Check whether pyRevit repo has core updates.
This would require host application to be closed to release the file lock
of core DLLs so they can be updated separately.
"""
pyrevit_repo = versionmgr.get_pyrevit_repo()
if pyrevit_repo and get_updates(pyrevit_repo):
new_commits = libgit.get_all_new_commits(pyrevit_repo)
logger.debug('Checking new commits on pyrevit repo.')
for cmt_sha, cmt_msg in new_commits.items():
logger.debug('%s: %s', cmt_sha, cmt_msg)
if COREUPDATE_TRIGGER in cmt_msg:
logger.debug('pyrevit repo has core update at %s: %s',
cmt_sha, cmt_msg)
return True
return False
``` | ### `update_pyrevit()` Update pyrevit and its extension repositories. Source code in `pyrevitlib/pyrevit/versionmgr/updater.py` | | | | --- | --- | | ```
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
``` | ```md-code__content
def update_pyrevit():
"""Update pyrevit and its extension repositories."""
if _check_connection():
third_party_updated = False
pyrevit_updated = False
pyrevit_has_coreupdates = has_core_updates()
thirdparty_repos = get_thirdparty_ext_repos()
logger.debug('List of thirdparty repos to be updated: %s',
thirdparty_repos)
# update third-party extensions first, one by one
for repo_info in thirdparty_repos:
logger.debug('Updating repo: %s', repo_info.directory)
try:
upped_repo_info = update_repo(repo_info)
logger.info(':inbox_tray: Successfully updated: %s to %s',
upped_repo_info.name,
upped_repo_info.last_commit_hash[:7])
third_party_updated = True
except Exception:
logger.info('Can not update repo: %s (Run in debug to see why)',
repo_info.name)
# now update pyrevit repo and reload
pyrevit_repo = versionmgr.get_pyrevit_repo()
if pyrevit_repo:
if not pyrevit_has_coreupdates:
logger.debug('Updating pyrevit repo: %s',
pyrevit_repo.directory)
try:
upped_pyrevit_repo_info = update_repo(pyrevit_repo)
logger.info(':inbox_tray: Successfully updated: %s to %s',
upped_pyrevit_repo_info.name,
upped_pyrevit_repo_info.last_commit_hash[:7])
pyrevit_updated = True
except Exception as err:
logger.info('Can not update pyrevit repo '
'(Run in debug to see why) | %s', err)
# perform upgrade tasks
logger.info('Upgrading settings...')
upgrade.upgrade_existing_pyrevit()
if not pyrevit_has_coreupdates:
if third_party_updated or pyrevit_updated:
# now reload pyrevit
from pyrevit.loader import sessionmgr
sessionmgr.reload_pyrevit()
else:
logger.info('pyRevit and extensions seem to be up-to-date.')
else:
from pyrevit import script
output = script.get_output()
output.print_html(COREUPDATE_MESSAGE)
logger.debug('Core updates. Skippin update and reload.')
else:
logger.warning('No internet access detected. Skipping update.')
``` | Back to top ## Extension Binary Caching [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/cacher_bin/#pyrevit.extensions.cacher_bin) # cacher\_bin Base module to handle extension binary caching. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `loaded_extensions = []``module-attribute` ## Classes ## Functions ### `update_cache(parsed_ext)` Source code in `pyrevitlib/pyrevit/extensions/cacher_bin.py` | | | | --- | --- | | ```
20
21
22
23
24
25
26
27
28
29
``` | ```md-code__content
def update_cache(parsed_ext):
try:
mlogger.debug('Writing cache for: %s', parsed_ext)
cache_file = _get_cache_file(parsed_ext)
mlogger.debug('Cache file is: %s', cache_file)
with open(cache_file, 'wb') as bin_cache_file:
pickle.dump(parsed_ext, bin_cache_file, pickle.HIGHEST_PROTOCOL)
except Exception as err:
raise PyRevitException('Error writing cache for: {} | {}'
.format(parsed_ext, err))
``` | ### `get_cached_extension(installed_ext)` Source code in `pyrevitlib/pyrevit/extensions/cacher_bin.py` | | | | --- | --- | | ```
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
``` | ```md-code__content
def get_cached_extension(installed_ext):
for loaded_ext in loaded_extensions:
if loaded_ext.name == installed_ext.name:
return loaded_ext
try:
mlogger.debug('Reading cache for: %s', installed_ext)
cache_file = _get_cache_file(installed_ext)
mlogger.debug('Cache file is: %s', cache_file)
with open(cache_file, 'rb') as bin_cache_file:
unpickled_pkg = pickle.load(bin_cache_file)
except Exception as err:
raise PyRevitException('Error reading cache for: {} | {}'
.format(installed_ext, err))
return unpickled_pkg
``` | ### `is_cache_valid(extension)` Source code in `pyrevitlib/pyrevit/extensions/cacher_bin.py` | | | | --- | --- | | ```
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
``` | ```md-code__content
def is_cache_valid(extension):
try:
cached_ext = get_cached_extension(extension)
mlogger.debug('Extension cache directory is: %s for: %s',
extension.directory, extension)
cache_dir_valid = \
cached_ext.directory == extension.directory
mlogger.debug('Extension cache version is: %s for: %s',
extension.pyrvt_version, extension)
cache_version_valid = \
cached_ext.pyrvt_version == extension.pyrvt_version
mlogger.debug('Extension hash value is: %s for: %s',
extension.dir_hash_value, extension)
cache_hash_valid = \
cached_ext.dir_hash_value == extension.dir_hash_value
cache_valid = \
cache_dir_valid and cache_version_valid and cache_hash_valid
# add loaded package to list so it can be recovered later
if cache_valid:
loaded_extensions.append(cached_ext)
# cache is valid if both version and hash value match
return cache_valid
except PyRevitException as err:
mlogger.debug('Error reading cache file or file is not available: %s',
err)
return False
except Exception as err:
mlogger.debug('Error determining cache validity: %s | %s',
extension, err)
return False
``` | Back to top ## Python Type Maker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/pythontypemaker/#pyrevit.runtime.pythontypemaker) # pythontypemaker Prepare and compile python script types. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_executor_type(extension, module_builder, cmd_component)` Create the dotnet type for the executor. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | | `module_builder` | `ModuleBuilder` | module builder | _required_ | | `cmd_component` | `GenericUICommand` | command | _required_ | Source code in `pyrevitlib/pyrevit/runtime/pythontypemaker.py` | | | | --- | --- | | ```
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
``` | ```md-code__content
def create_executor_type(extension, module_builder, cmd_component):
"""Create the dotnet type for the executor.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
module_builder (ModuleBuilder): module builder
cmd_component (pyrevit.extensions.genericcomps.GenericUICommand):
command
"""
cmd_component.requires_clean_engine = \
_does_need_clean_engine(extension, cmd_component)
engine_configs = runtime.create_ipyengine_configs(
clean=cmd_component.requires_clean_engine,
full_frame=cmd_component.requires_fullframe_engine,
persistent=cmd_component.requires_persistent_engine,
)
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component,
eng_cfgs=engine_configs
)
``` | Back to top ## Markdown to HTML [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/markdown/#pyrevit.coreutils.markdown) # markdown Python Markdown. Python Markdown converts Markdown to HTML and can be used as a library or called from the command line. ### Basic usage as a module: ``` import markdown html = markdown.markdown(your_text_string) ``` See [https://pythonhosted.org/Markdown/](https://pythonhosted.org/Markdown/) for more information and instructions on how to extend the functionality of Python Markdown. Read that before you try modifying this file. ### Authors and License Started by [Manfred Stienstra](http://www.dwerg.net/). Continued and maintained by [Yuri Takhteyev](http://www.freewisdom.org/), [Waylan\\ Limberg](http://achinghead.com/) and [Artem Yunusov](http://blog.splyer.com/). Contact: markdown@freewisdom.org Copyright 2007-2013 The Python Markdown Project (v. 1.7 and later) Copyright 200? Django Software Foundation (OrderedDict implementation) Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) Copyright 2004 Manfred Stienstra (the original version) License: BSD (see LICENSE for details). ## Attributes ### `logger = logging.getLogger('MARKDOWN')``module-attribute` ## Classes ### `Markdown(*args, **kwargs)` Bases: `object` Convert Markdown to HTML. Creates a new Markdown instance. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*args` | `Any` | positional args | `()` | | `**kwargs` | `Any` | keyword args | `{}` | Other Parameters: | Name | Type | Description | | --- | --- | --- | | `extensions` | `list[Extension | str]` | A list of extensions.
If they are of type string, the module mdx\_name.py will be loaded.
If they are a subclass of markdown.Extension, they will be used
as-is. | | `extension_configs` | `dict[str, Any]` | Configuration settings for extensions. | | `output_format` | `str` | Format of output. Supported formats are:
\\* "xhtml1": Outputs XHTML 1.x. Default.
\\* "xhtml5": Outputs XHTML style tags of HTML 5
\\* "xhtml": Outputs latest supported version of XHTML
(currently XHTML 1.1).
\\* "html4": Outputs HTML 4
\\* "html5": Outputs HTML style tags of HTML 5
\\* "html": Outputs latest supported version of HTML
(currently HTML 4).
Note that it is suggested that the more specific formats ("xhtml1"
and "html4") be used as "xhtml" or "html" may change in the future
if it makes sense at that time. | | `safe_mode` | `str` | Deprecated! Disallow raw html.
One of "remove", "replace" or "escape". | | `html_replacement_text` | `str` | Deprecated! Text used when safe\_mode
is set to "replace". | | `tab_length` | `int` | Length of tabs in the source. Default: 4 | | `enable_attributes` | `bool` | Enable the conversion of attributes.
Default: True | | `smart_emphasis` | `bool` | Treat `_connected_words_` intelligently
Default: True | | `lazy_ol` | `bool` | Ignore number of first item of ordered lists.
Default: True | Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
``` | ```md-code__content
def __init__(self, *args, **kwargs):
"""Creates a new Markdown instance.
Args:
*args (Any): positional args
**kwargs (Any): keyword args
Keyword Args:
extensions (list[Extension | str]): A list of extensions.
If they are of type string, the module mdx_name.py will be loaded.
If they are a subclass of markdown.Extension, they will be used
as-is.
extension_configs (dict[str, Any]): Configuration settings for extensions.
output_format (str): Format of output. Supported formats are:
* "xhtml1": Outputs XHTML 1.x. Default.
* "xhtml5": Outputs XHTML style tags of HTML 5
* "xhtml": Outputs latest supported version of XHTML
(currently XHTML 1.1).
* "html4": Outputs HTML 4
* "html5": Outputs HTML style tags of HTML 5
* "html": Outputs latest supported version of HTML
(currently HTML 4).
Note that it is suggested that the more specific formats ("xhtml1"
and "html4") be used as "xhtml" or "html" may change in the future
if it makes sense at that time.
safe_mode (str): Deprecated! Disallow raw html.
One of "remove", "replace" or "escape".
html_replacement_text (str): Deprecated! Text used when safe_mode
is set to "replace".
tab_length (int): Length of tabs in the source. Default: 4
enable_attributes (bool): Enable the conversion of attributes.
Default: True
smart_emphasis (bool): Treat `_connected_words_` intelligently
Default: True
lazy_ol (bool): Ignore number of first item of ordered lists.
Default: True
"""
# For backward compatibility, loop through old positional args
pos = ['extensions', 'extension_configs', 'safe_mode', 'output_format']
for c, arg in enumerate(args):
if pos[c] not in kwargs:
kwargs[pos[c]] = arg
if c+1 == len(pos): # pragma: no cover
# ignore any additional args
break
if len(args):
warnings.warn('Positional arguments are deprecated in Markdown. '
'Use keyword arguments only.',
DeprecationWarning)
# Loop through kwargs and assign defaults
for option, default in self.option_defaults.items():
setattr(self, option, kwargs.get(option, default))
self.safeMode = kwargs.get('safe_mode', False)
if self.safeMode and 'enable_attributes' not in kwargs:
# Disable attributes in safeMode when not explicitly set
self.enable_attributes = False
if 'safe_mode' in kwargs:
warnings.warn('"safe_mode" is deprecated in Python-Markdown. '
'Use an HTML sanitizer (like '
'Bleach https://bleach.readthedocs.io/) '
'if you are parsing untrusted markdown text. '
'See the 2.6 release notes for more info',
DeprecationWarning)
if 'html_replacement_text' in kwargs:
warnings.warn('The "html_replacement_text" keyword is '
'deprecated along with "safe_mode".',
DeprecationWarning)
self.ESCAPED_CHARS = ['\\', '`', '*', '_', '{', '}', '[', ']',
'(', ')', '>', '#', '+', '-', '.', '!']
self.registeredExtensions = []
self.docType = ""
self.stripTopLevelTags = True
self.build_parser()
self.references = {}
self.htmlStash = util.HtmlStash()
self.registerExtensions(extensions=kwargs.get('extensions', []),
configs=kwargs.get('extension_configs', {}))
self.set_output_format(kwargs.get('output_format', 'xhtml1'))
self.reset()
``` | #### Attributes ##### `doc_tag = 'div'``class-attribute``instance-attribute` ##### `option_defaults = {'html_replacement_text': '[HTML_REMOVED]', 'tab_length': 4, 'enable_attributes': True, 'smart_emphasis': True, 'lazy_ol': True}``class-attribute``instance-attribute` ##### `output_formats = {'html': to_html_string, 'html4': to_html_string, 'html5': to_html_string, 'xhtml': to_xhtml_string, 'xhtml1': to_xhtml_string, 'xhtml5': to_xhtml_string}``class-attribute``instance-attribute` ##### `safeMode = kwargs.get('safe_mode', False)``instance-attribute` ##### `enable_attributes = False``instance-attribute` ##### ``ESCAPED_CHARS = ['\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '\#', '+', '-', '.', '!']```instance-attribute` ##### `registeredExtensions = []``instance-attribute` ##### `docType = ''``instance-attribute` ##### `stripTopLevelTags = True``instance-attribute` ##### `references = {}``instance-attribute` ##### `htmlStash = util.HtmlStash()``instance-attribute` #### Functions ##### `build_parser()` Build the parser from the various parts. Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
166
167
168
169
170
171
172
173
``` | ```md-code__content
def build_parser(self):
"""Build the parser from the various parts."""
self.preprocessors = build_preprocessors(self)
self.parser = build_block_parser(self)
self.inlinePatterns = build_inlinepatterns(self)
self.treeprocessors = build_treeprocessors(self)
self.postprocessors = build_postprocessors(self)
return self
``` | ##### `registerExtensions(extensions, configs)` Register extensions with this instance of Markdown. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extensions` | `list[Extension]` | extensions strings or objects.
See the docstring on Markdown. | _required_ | | `configs` | `dict[str, Any]` | A dictionary mapping module names to config options. | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
``` | ```md-code__content
def registerExtensions(self, extensions, configs):
"""Register extensions with this instance of Markdown.
Args:
extensions (list[Extension]): extensions strings or objects.
See the docstring on Markdown.
configs (dict[str, Any]): A dictionary mapping module names to config options.
"""
for ext in extensions:
if isinstance(ext, util.string_type):
ext = self.build_extension(ext, configs.get(ext, {}))
if isinstance(ext, Extension):
ext.extendMarkdown(self, globals())
logger.debug(
'Successfully loaded extension "%s.%s".'
% (ext.__class__.__module__, ext.__class__.__name__)
)
elif ext is not None:
raise TypeError(
'Extension "%s.%s" must be of type: "markdown.Extension"'
% (ext.__class__.__module__, ext.__class__.__name__))
return self
``` | ##### `build_extension(ext_name, configs)` Build extension by name, then return the module. The extension name may contain arguments as part of the string in the following format: "extname(key1=value1,key2=value2)" Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
``` | ```md-code__content
def build_extension(self, ext_name, configs):
"""Build extension by name, then return the module.
The extension name may contain arguments as part of the string in the
following format: "extname(key1=value1,key2=value2)"
"""
configs = dict(configs)
# Parse extensions config params (ignore the order)
pos = ext_name.find("(") # find the first "("
if pos > 0:
ext_args = ext_name[pos+1:-1]
ext_name = ext_name[:pos]
pairs = [x.split("=") for x in ext_args.split(",")]
configs.update([(x.strip(), y.strip()) for (x, y) in pairs])
warnings.warn('Setting configs in the Named Extension string is '
'deprecated. It is recommended that you '
'pass an instance of the extension class to '
'Markdown or use the "extension_configs" keyword. '
'The current behavior will raise an error in version 2.7. '
'See the Release Notes for Python-Markdown version '
'2.6 for more info.', DeprecationWarning)
# Get class name (if provided): `path.to.module:ClassName`
ext_name, class_name = ext_name.split(':', 1) \
if ':' in ext_name else (ext_name, '')
# Try loading the extension first from one place, then another
try:
# Assume string uses dot syntax (`path.to.some.module`)
module = importlib.import_module(ext_name)
logger.debug(
'Successfuly imported extension module "%s".' % ext_name
)
# For backward compat (until deprecation)
# check that this is an extension.
if ('.' not in ext_name and not (hasattr(module, 'makeExtension') or
(class_name and hasattr(module, class_name)))):
# We have a name conflict
# eg: extensions=['tables'] and PyTables is installed
raise ImportError
except ImportError:
# Preppend `markdown.extensions.` to name
module_name = '.'.join(['markdown.extensions', ext_name])
try:
module = importlib.import_module(module_name)
logger.debug(
'Successfuly imported extension module "%s".' %
module_name
)
warnings.warn('Using short names for Markdown\'s builtin '
'extensions is deprecated. Use the '
'full path to the extension with Python\'s dot '
'notation (eg: "%s" instead of "%s"). The '
'current behavior will raise an error in version '
'2.7. See the Release Notes for '
'Python-Markdown version 2.6 for more info.' %
(module_name, ext_name),
DeprecationWarning)
except ImportError:
# Preppend `mdx_` to name
module_name_old_style = '_'.join(['mdx', ext_name])
try:
module = importlib.import_module(module_name_old_style)
logger.debug(
'Successfuly imported extension module "%s".' %
module_name_old_style)
warnings.warn('Markdown\'s behavior of prepending "mdx_" '
'to an extension name is deprecated. '
'Use the full path to the '
'extension with Python\'s dot notation '
'(eg: "%s" instead of "%s"). The current '
'behavior will raise an error in version 2.7. '
'See the Release Notes for Python-Markdown '
'version 2.6 for more info.' %
(module_name_old_style, ext_name),
DeprecationWarning)
except ImportError as e:
message = "Failed loading extension '%s' from '%s', '%s' " \
"or '%s'" % (ext_name, ext_name, module_name,
module_name_old_style)
e.args = (message,) + e.args[1:]
raise
if class_name:
# Load given class name from module.
return getattr(module, class_name)(**configs)
else:
# Expect makeExtension() function to return a class.
try:
return module.makeExtension(**configs)
except AttributeError as e:
message = e.args[0]
message = "Failed to initiate extension " \
"'%s': %s" % (ext_name, message)
e.args = (message,) + e.args[1:]
raise
``` | ##### `registerExtension(extension)` This gets called by the extension. Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
299
300
301
302
``` | ```md-code__content
def registerExtension(self, extension):
"""This gets called by the extension."""
self.registeredExtensions.append(extension)
return self
``` | ##### `reset()` Resets all state variables so that we can start with a new text. Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
304
305
306
307
308
309
310
311
312
313
``` | ```md-code__content
def reset(self):
"""Resets all state variables so that we can start with a new text."""
self.htmlStash.reset()
self.references.clear()
for extension in self.registeredExtensions:
if hasattr(extension, 'reset'):
extension.reset()
return self
``` | ##### `set_output_format(format)` Set the output format for the class instance. Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
315
316
317
318
319
320
321
322
323
324
325
326
327
328
``` | ```md-code__content
def set_output_format(self, format):
"""Set the output format for the class instance."""
self.output_format = format.lower()
try:
self.serializer = self.output_formats[self.output_format]
except KeyError as e:
valid_formats = list(self.output_formats.keys())
valid_formats.sort()
message = 'Invalid Output Format: "%s". Use one of %s.' \
% (self.output_format,
'"' + '", "'.join(valid_formats) + '"')
e.args = (message,) + e.args[1:]
raise
return self
``` | ##### `convert(source)` Convert markdown to serialized XHTML or HTML. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source` | `str` | Source text as a Unicode string. | _required_ | Markdown processing takes place in five steps: 1. A bunch of "preprocessors" munge the input text. 2. BlockParser() parses the high-level structural elements of the pre-processed text into an ElementTree. 3. A bunch of "treeprocessors" are run against the ElementTree. One such treeprocessor runs InlinePatterns against the ElementTree, detecting inline markup. 4. Some post-processors are run against the text after the ElementTree has been serialized into text. 5. The output is written to a string. Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
``` | ```md-code__content
def convert(self, source):
"""Convert markdown to serialized XHTML or HTML.
Args:
source (str): Source text as a Unicode string.
Markdown processing takes place in five steps:
1. A bunch of "preprocessors" munge the input text.
2. BlockParser() parses the high-level structural elements of the
pre-processed text into an ElementTree.
3. A bunch of "treeprocessors" are run against the ElementTree. One
such treeprocessor runs InlinePatterns against the ElementTree,
detecting inline markup.
4. Some post-processors are run against the text after the ElementTree
has been serialized into text.
5. The output is written to a string.
"""
# Fixup the source text
if not source.strip():
return '' # a blank unicode string
try:
source = unicode(source)
except UnicodeDecodeError as e:
# Customise error message while maintaining original trackback
e.reason += '. -- Note: Markdown only accepts unicode input!'
raise
# Split into lines and run the line preprocessors.
self.lines = source.split("\n")
for prep in self.preprocessors.values():
self.lines = prep.run(self.lines)
# Parse the high-level elements.
root = self.parser.parseDocument(self.lines).getroot()
# Run the tree-processors
for treeprocessor in self.treeprocessors.values():
newRoot = treeprocessor.run(root)
if newRoot is not None:
root = newRoot
# Serialize _properly_. Strip top-level tags.
output = self.serializer(root)
if self.stripTopLevelTags:
try:
start = output.index(
'<%s>' % self.doc_tag) + len(self.doc_tag) + 2
end = output.rindex('' % self.doc_tag)
output = output[start:end].strip()
except ValueError: # pragma: no cover
if output.strip().endswith('<%s />' % self.doc_tag):
# We have an empty document
output = ''
else:
# We have a serious problem
raise ValueError('Markdown failed to strip top-level '
'tags. Document=%r' % output.strip())
# Run the text post-processors
for pp in self.postprocessors.values():
output = pp.run(output)
return output.strip()
``` | ##### `convertFile(input=None, output=None, encoding=None)` Converts a Markdown file and returns the HTML as a Unicode string. Decodes the file using the provided encoding (defaults to utf-8), passes the file content to markdown, and outputs the html to either the provided stream or the file with provided name, using the same encoding as the source file. The 'xmlcharrefreplace' error handler is used when encoding the output. **Note:** This is the only place that decoding and encoding of Unicode takes place in Python-Markdown. (All other code is Unicode-in / Unicode-out.) Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `input` | `str | None` | File object or path. Reads from stdin if `None`. | `None` | | `output` | `str | None` | File object or path. Writes to stdout if `None`. | `None` | | `encoding` | `str` | Encoding of input and output files. Defaults to utf-8. | `None` | Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
``` | ```md-code__content
def convertFile(self, input=None, output=None, encoding=None):
"""Converts a Markdown file and returns the HTML as a Unicode string.
Decodes the file using the provided encoding (defaults to utf-8),
passes the file content to markdown, and outputs the html to either
the provided stream or the file with provided name, using the same
encoding as the source file. The 'xmlcharrefreplace' error handler is
used when encoding the output.
**Note:** This is the only place that decoding and encoding of Unicode
takes place in Python-Markdown. (All other code is Unicode-in /
Unicode-out.)
Args:
input (str | None): File object or path. Reads from stdin if `None`.
output (str | None): File object or path. Writes to stdout if `None`.
encoding (str): Encoding of input and output files. Defaults to utf-8.
"""
encoding = encoding or "utf-8"
# Read the source
if input:
if isinstance(input, util.string_type):
input_file = codecs.open(input, mode="r", encoding=encoding)
else:
input_file = codecs.getreader(encoding)(input)
text = input_file.read()
input_file.close()
else:
text = sys.stdin.read()
if not isinstance(text, util.text_type):
text = text.decode(encoding)
text = text.lstrip('\ufeff') # remove the byte-order mark
# Convert
html = self.convert(text)
# Write to file or stdout
if output:
if isinstance(output, util.string_type):
output_file = codecs.open(output, "w",
encoding=encoding,
errors="xmlcharrefreplace")
output_file.write(html)
output_file.close()
else:
writer = codecs.getwriter(encoding)
output_file = writer(output, errors="xmlcharrefreplace")
output_file.write(html)
# Don't close here. User may want to write more.
else:
# Encode manually and write bytes to stdout.
html = html.encode(encoding, "xmlcharrefreplace")
try:
# Write bytes directly to buffer (Python 3).
sys.stdout.buffer.write(html)
except AttributeError:
# Probably Python 2, which works with bytes by default.
sys.stdout.write(html)
return self
``` | ## Functions ### `markdown(text, *args, **kwargs)` Convert a Markdown string to HTML and return HTML as a Unicode string. This is a shortcut function for `Markdown` class to cover the most basic use case. It initializes an instance of Markdown, loads the necessary extensions and runs the parser on the given text. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `text` | `str` | Markdown formatted text as Unicode or ASCII string. | _required_ | | `*args` | `Any` | Any arguments accepted by the Markdown class. | `()` | | `**kwargs` | `Any` | Any arguments accepted by the Markdown class. | `{}` | Returns: | Type | Description | | --- | --- | | `str` | An HTML document as a string. | Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
``` | ```md-code__content
def markdown(text, *args, **kwargs):
"""Convert a Markdown string to HTML and return HTML as a Unicode string.
This is a shortcut function for `Markdown` class to cover the most
basic use case. It initializes an instance of Markdown, loads the
necessary extensions and runs the parser on the given text.
Args:
text (str): Markdown formatted text as Unicode or ASCII string.
*args (Any): Any arguments accepted by the Markdown class.
**kwargs (Any): Any arguments accepted by the Markdown class.
Returns:
(str): An HTML document as a string.
"""
md = Markdown(*args, **kwargs)
return md.convert(text)
``` | ### `markdownFromFile(*args, **kwargs)` Read markdown code from a file and write it to a file or a stream. This is a shortcut function which initializes an instance of Markdown, and calls the convertFile method rather than convert. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `*args` | `Any` | Any arguments accepted by the Markdown class.
input (str): a file name or readable object.
output (str): a file name or writable object.
encoding (str): Encoding of input and output. | `()` | | `**kwargs` | `Any` | Any arguments accepted by the Markdown class. | `{}` | Source code in `pyrevitlib/pyrevit/coreutils/markdown/__init__.py` | | | | --- | --- | | ```
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
``` | ```md-code__content
def markdownFromFile(*args, **kwargs):
"""Read markdown code from a file and write it to a file or a stream.
This is a shortcut function which initializes an instance of Markdown,
and calls the convertFile method rather than convert.
Args:
*args (Any): Any arguments accepted by the Markdown class.
input (str): a file name or readable object.
output (str): a file name or writable object.
encoding (str): Encoding of input and output.
**kwargs (Any): Any arguments accepted by the Markdown class.
"""
# For backward compatibility loop through positional args
pos = ['input', 'output', 'extensions', 'encoding']
c = 0
for arg in args:
if pos[c] not in kwargs:
kwargs[pos[c]] = arg
c += 1
if c == len(pos):
break
if len(args):
warnings.warn('Positional arguments are depreacted in '
'Markdown and will raise an error in version 2.7. '
'Use keyword arguments only.',
DeprecationWarning)
md = Markdown(**kwargs)
md.convertFile(kwargs.get('input', None),
kwargs.get('output', None),
kwargs.get('encoding', None))
``` | Back to top ## pyRevit Hooks Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/loader/hooks/#pyrevit.loader.hooks) # hooks Hooks management. ## Attributes ### `SUPPORTED_LANGUAGES = [exts.PYTHON_SCRIPT_FILE_FORMAT, exts.CSHARP_SCRIPT_FILE_FORMAT, exts.VB_SCRIPT_FILE_FORMAT]``module-attribute` ### `mlogger = get_logger(__name__)``module-attribute` ### `ExtensionEventHook = namedtuple('ExtensionEventHook', ['id', 'name', 'target', 'script', 'syspaths', 'extension_name'])``module-attribute` ## Functions ### `get_hooks_handler()` Get the hook handler environment variable. Returns: | Type | Description | | --- | --- | | `EventHooks` | hook handler | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
37
38
39
40
41
42
43
``` | ```md-code__content
def get_hooks_handler():
"""Get the hook handler environment variable.
Returns:
(EventHooks): hook handler
"""
return envvars.get_pyrevit_env_var(envvars.HOOKSHANDLER_ENVVAR)
``` | ### `set_hooks_handler(handler)` Set the hook handler environment variable. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `handler` | `EventHooks` | hook handler | _required_ | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
46
47
48
49
50
51
52
``` | ```md-code__content
def set_hooks_handler(handler):
"""Set the hook handler environment variable.
Args:
handler (EventHooks): hook handler
"""
envvars.set_pyrevit_env_var(envvars.HOOKSHANDLER_ENVVAR, handler)
``` | ### `is_valid_hook_script(hook_script)` Check if the given hook script is valid. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `hook_script` | `str` | hook script path | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if the script is valid, False otherwise | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
55
56
57
58
59
60
61
62
63
64
``` | ```md-code__content
def is_valid_hook_script(hook_script):
"""Check if the given hook script is valid.
Args:
hook_script (str): hook script path
Returns:
(bool): True if the script is valid, False otherwise
"""
return op.splitext(op.basename(hook_script))[1] in SUPPORTED_LANGUAGES
``` | ### `get_extension_hooks(extension)` Get the hooks of the given extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | Returns: | Type | Description | | --- | --- | | `list[ExtensionEventHook]` | list of hooks | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
``` | ```md-code__content
def get_extension_hooks(extension):
"""Get the hooks of the given extension.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
Returns:
(list[ExtensionEventHook]): list of hooks
"""
event_hooks = []
for hook_script in extension.get_hooks():
if is_valid_hook_script(hook_script):
name, target = _get_hook_parts(extension, hook_script)
if name:
event_hooks.append(
ExtensionEventHook(
id=_create_hook_id(extension, hook_script),
name=name,
target=target,
script=hook_script,
syspaths=extension.module_paths,
extension_name=extension.name,
)
)
return event_hooks
``` | ### `get_event_hooks()` Get all the event hooks. Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
117
118
119
120
``` | ```md-code__content
def get_event_hooks():
"""Get all the event hooks."""
hooks_handler = get_hooks_handler()
return hooks_handler.GetAllEventHooks()
``` | ### `register_hooks(extension)` Register the hooks for the given extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
``` | ```md-code__content
def register_hooks(extension):
"""Register the hooks for the given extension.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
"""
hooks_handler = get_hooks_handler()
for ext_hook in get_extension_hooks(extension):
try:
hooks_handler.RegisterHook(
uniqueId=ext_hook.id,
eventName=ext_hook.name,
eventTarget=ext_hook.target,
scriptPath=ext_hook.script,
searchPaths=framework.Array[str](ext_hook.syspaths),
extensionName=ext_hook.extension_name,
)
except Exception as hookEx:
mlogger.error("Failed registering hook script %s | %s",
ext_hook.script, hookEx)
``` | ### `unregister_hooks(extension)` Unregister all hooks for the given extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
145
146
147
148
149
150
151
152
153
``` | ```md-code__content
def unregister_hooks(extension):
"""Unregister all hooks for the given extension.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
"""
hooks_handler = get_hooks_handler()
for ext_hook in get_extension_hooks(extension):
hooks_handler.UnRegisterHook(uniqueId=ext_hook.id)
``` | ### `unregister_all_hooks()` Unregister all hooks. Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
156
157
158
159
``` | ```md-code__content
def unregister_all_hooks():
"""Unregister all hooks."""
hooks_handler = get_hooks_handler()
hooks_handler.UnRegisterAllHooks(uiApp=HOST_APP.uiapp)
``` | ### `activate()` Activate all event hooks. Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
162
163
164
165
``` | ```md-code__content
def activate():
"""Activate all event hooks."""
hooks_handler = get_hooks_handler()
hooks_handler.ActivateEventHooks(uiApp=HOST_APP.uiapp)
``` | ### `deactivate()` Deactivate all event hooks. Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
168
169
170
171
``` | ```md-code__content
def deactivate():
"""Deactivate all event hooks."""
hooks_handler = get_hooks_handler()
hooks_handler.DeactivateEventHooks(uiApp=HOST_APP.uiapp)
``` | ### `setup_hooks(session_id=None)` Setup the hooks for the given session. If no session is specified, use the current one. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `session_id` | `str` | Session. Defaults to None. | `None` | Source code in `pyrevitlib/pyrevit/loader/hooks.py` | | | | --- | --- | | ```
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
``` | ```md-code__content
def setup_hooks(session_id=None):
"""Setup the hooks for the given session.
If no session is specified, use the current one.
Args:
session_id (str, optional): Session. Defaults to None.
"""
# make sure session id is availabe
if not session_id:
session_id = sessioninfo.get_session_uuid()
hooks_handler = get_hooks_handler()
if hooks_handler:
# deactivate old
hooks_handler.DeactivateEventHooks(uiApp=HOST_APP.uiapp)
# setup new
hooks_handler = EventHooks(session_id)
set_hooks_handler(hooks_handler)
unregister_all_hooks()
``` | Back to top ## HTML Card Generation [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/output/cards/#pyrevit.output.cards) # cards This module contains functions to generate HTML cards for use in pyRevit output. ## Functions ### `card_start_style(limit, value, alt)` Generates an HTML div element with a specific background color based on the ratio of value to limit. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `limit` | `float` | The limit value used to calculate the ratio. | _required_ | | `value` | `float` | The current value to be compared against the limit. | _required_ | | `alt` | `str` | The alt text for the div element. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | An HTML div element as a string with inline styles and the specified background color. | The background color is determined by the following rules: \- 'Grey' if value is 0 or if an exception occurs during ratio calculation. \- 'Green' if 0 <= ratio < 0.5. \- 'Orange' if 0.5 <= ratio <= 1. \- 'Red' if ratio > 1. Source code in `pyrevitlib/pyrevit/output/cards.py` | | | | --- | --- | | ```
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
``` | ```md-code__content
def card_start_style(limit, value, alt):
"""
Generates an HTML div element with a specific background color based on the ratio of value to limit.
Args:
limit (float): The limit value used to calculate the ratio.
value (float): The current value to be compared against the limit.
alt (str): The alt text for the div element.
Returns:
str: An HTML div element as a string with inline styles and the specified background color.
The background color is determined by the following rules:
- 'Grey' if value is 0 or if an exception occurs during ratio calculation.
- 'Green' if 0 <= ratio < 0.5.
- 'Orange' if 0.5 <= ratio <= 1.
- 'Red' if ratio > 1.
"""
try:
ratio = float(value) / float(limit)
except ZeroDivisionError:
ratio = 0
color = "#d0d3d4"
if value != 0:
if ratio < 0.5:
color = "#D0E6A5" # green
elif ratio <= 1:
color = "#FFDD94" # orange
else:
color = "#FA897B" # red
try:
card_start = '
'.format(
color, alt
)
except Exception as e:
print(e)
return card_start
``` | ### `card_builder(limit, value, description)` Builds an HTML card with the given limit, value, and description. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `limit` | `int` | The limit value to be displayed in the card. | _required_ | | `value` | `int or str` | The main value to be displayed in the card. | _required_ | | `description` | `str` | A description to be displayed in the card. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | A string containing the HTML representation of the card. | Source code in `pyrevitlib/pyrevit/output/cards.py` | | | | --- | --- | | ```
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
``` | ```md-code__content
def card_builder(limit, value, description):
"""
Builds an HTML card with the given limit, value, and description.
Args:
limit (int): The limit value to be displayed in the card.
value (int or str): The main value to be displayed in the card.
description (str): A description to be displayed in the card.
Returns:
str: A string containing the HTML representation of the card.
"""
alt = "{} {} (limit = {})".format(str(value), str(description), str(limit))
card_end = '{}
{}
'.format(
value, description
)
return card_start_style(limit, value, alt) + card_end
``` | ### `create_frame(title, *cards)` Creates an HTML div frame containing multiple cards with a rounded border and a title on the top left corner. return card\_start\_style(limit, value, alt) + card\_end cards (str): Multiple strings representing HTML card elements. Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | A string containing the HTML representation of the div frame. | Source code in `pyrevitlib/pyrevit/output/cards.py` | | | | --- | --- | | ```
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
``` | ```md-code__content
def create_frame(title, *cards):
"""
Creates an HTML div frame containing multiple cards with a rounded border and a title on the top left corner.
return card_start_style(limit, value, alt) + card_end
cards (str): Multiple strings representing HTML card elements.
Returns:
str: A string containing the HTML representation of the div frame.
"""
# Add vertical-align: top to the frame and adjust title position
frame_start = '
'
title_html = '
{}
'.format(
title
)
cards_html = "".join(cards)
frame_end = "
"
return frame_start + title_html + cards_html + frame_end
``` | Back to top ## Autodesk Desktop Connector [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/adc/#pyrevit.interop.adc) # adc Wrapping Autodesk Desktop Connector API. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `ADC_NAME = 'Autodesk Desktop Connector'``module-attribute` ### `ADC_SHORTNAME = 'ADC'``module-attribute` ### `ADC_DRIVE_SCHEMA = '{drive_name}://'``module-attribute` ### `ADC_DEFAULT_INSTALL_PATH = 'C:\\Program Files\\Autodesk\\Desktop Connector'``module-attribute` ### `ADC_API_DLL = 'Autodesk.DesktopConnector.API.dll'``module-attribute` ### `ADC_API_DLL_PATH = op.join(ADC_DEFAULT_INSTALL_PATH, ADC_API_DLL)``module-attribute` ## Classes ## Functions ### `is_available()` Check if ADC service is available. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
125
126
127
128
129
130
131
``` | ```md-code__content
def is_available():
"""Check if ADC service is available."""
try:
_get_adc().Discover()
return True
except Exception:
return False
``` | ### `get_drive_paths()` Get dict of local paths for ADC drives. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
134
135
136
137
``` | ```md-code__content
def get_drive_paths():
"""Get dict of local paths for ADC drives."""
adc = _get_adc()
return {x.Name: x.WorkspaceLocation for x in _get_drives_info(adc)}
``` | ### `get_local_path(path)` Convert ADC BIM360 drive path to local path. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
140
141
142
143
144
145
``` | ```md-code__content
def get_local_path(path):
"""Convert ADC BIM360 drive path to local path."""
adc = _get_adc()
drv_info = _get_drive_from_path(adc, path)
if drv_info:
return _drive_path_to_local_path(drv_info, path)
``` | ### `lock_file(path)` Lock given file. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
148
149
150
151
152
``` | ```md-code__content
def lock_file(path):
"""Lock given file."""
adc = _get_adc()
item = _get_item(adc, path)
adc.LockFile(item.Id)
``` | ### `is_locked(path)` Check if file is locked. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
155
156
157
158
159
160
161
``` | ```md-code__content
def is_locked(path):
"""Check if file is locked."""
adc = _get_adc()
item = _get_item(adc, path)
lock_status = _get_item_lockstatus(adc, item)
return lock_status.State == API.LockState.LockedByOther, \
lock_status.LockOwner
``` | ### `unlock_file(path)` Unlock given file. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
164
165
166
167
168
``` | ```md-code__content
def unlock_file(path):
"""Unlock given file."""
adc = _get_adc()
item = _get_item(adc, path)
adc.UnlockFile(item.Id)
``` | ### `is_synced(path)` Check if file is synchronized. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
``` | ```md-code__content
def is_synced(path):
"""Check if file is synchronized."""
adc = _get_adc()
item = _get_item(adc, path)
drive = _get_item_drive(adc, item)
# ADC uses translated property names so
# check status property by its type "LocalState"
# see https://github.com/pyrevitlabs/pyRevit/issues/1152
# ADC version 15 changed property_id_value
# see https://github.com/pyrevitlabs/pyRevit/issues/1371
prop_val = _get_item_property_id_value(adc, drive, item, 'DesktopConnector.Core.LocalState')
if prop_val is None:
# version older than ADC 15
prop_val = _get_item_property_id_value(adc, drive, item, 'LocalState')
# possible values, 'Cached', 'Stale', 'Modified'
# .Value is not translated
return prop_val.Value == 'Cached'or prop_val.Value == 'Synced'
``` | ### `sync_file(path, force=False)` Force ADC to sync given file to latest version. Source code in `pyrevitlib/pyrevit/interop/adc.py` | | | | --- | --- | | ```
190
191
192
193
194
195
196
197
198
199
200
``` | ```md-code__content
def sync_file(path, force=False):
"""Force ADC to sync given file to latest version."""
if not force and is_synced(path):
return
adc = _get_adc()
item = _get_item(adc, path)
# make sure path is local
local_path = _ensure_local_path(adc, path)
for proc_id in _get_all_processids():
adc.FileClosedWithinRunningProcess(proc_id, local_path)
adc.SyncFiles([item.Id])
``` | Back to top ## Generic Extension Components [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/genericcomps/#pyrevit.extensions.genericcomps) # genericcomps Generic extension components. ## Attributes ### `mlogger = coreutils.logger.get_logger(__name__)``module-attribute` ### `EXT_DIR_KEY = 'directory'``module-attribute` ### `SUB_CMP_KEY = 'components'``module-attribute` ### `LAYOUT_ITEM_KEY = 'layout_items'``module-attribute` ### `LAYOUT_DIR_KEY = 'directive'``module-attribute` ### `TYPE_ID_KEY = 'type_id'``module-attribute` ### `NAME_KEY = 'name'``module-attribute` ## Classes ### `TypedComponent` Bases: `object` Component with a type id. #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ### `CachableComponent` Bases: `TypedComponent` Cacheable Component. #### Attributes ##### `type_id = None``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ### `LayoutDirective(directive_type=None, target=None)` Bases: `CachableComponent` Layout directive. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
50
51
52
``` | ```md-code__content
def __init__(self, directive_type=None, target=None):
self.directive_type = directive_type
self.target = target
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `directive_type = directive_type``instance-attribute` ##### `target = target``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ### `LayoutItem(name=None, directive=None)` Bases: `CachableComponent` Layout item. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
57
58
59
``` | ```md-code__content
def __init__(self, name=None, directive=None):
self.name = name
self.directive = directive
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = name``instance-attribute` ##### `directive = directive``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ### `GenericComponent()` Bases: `CachableComponent` Generic component object. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
64
65
``` | ```md-code__content
def __init__(self):
self.name = None
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ### `GenericUIComponent(cmp_path=None)` Bases: `GenericComponent` Generic UI component. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
GenericComponent.__init__(self)
self.directory = cmp_path
self.unique_name = self.parent_ctrl_id = None
self.icon_file = None
self._ui_title = None
self._tooltip = self.author = self._help_url = None
self.media_file = None
self.min_revit_ver = self.max_revit_ver = None
self.is_beta = False
self.highlight_type = None
self.collapsed = False
self.version = None
self.meta = {}
self.meta_file = None
self.modules = []
self.module_paths = []
self.binary_path = None
self.library_path = None
if self.directory:
self._update_from_directory()
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ### `GenericUIContainer(cmp_path=None)` Bases: `GenericUIComponent` Superclass for all UI group items (tab, panel, button groups, stacks). Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `allowed_sub_cmps = []``class-attribute``instance-attribute` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ### `GenericUICommand(cmp_path=None, needs_script=True)` Bases: `GenericUIComponent` Superclass for all single commands. The information provided by these classes will be used to create a push button under Revit UI. However, pyRevit expands the capabilities of push button beyond what is provided by Revit UI. (e.g. Toggle button changes it's icon based on its on/off status) See LinkButton and ToggleButton classes. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_script=True):
self.needs_script = needs_script
self.script_file = self.config_script_file = None
self.arguments = []
self.context = None
self.class_name = self.avail_class_name = None
self.requires_clean_engine = False
self.requires_fullframe_engine = False
self.requires_persistent_engine = False
self.requires_mainthread_engine = False
# engine options specific to dynamo
self.dynamo_path = None
# self.dynamo_path_exec = False
self.dynamo_path_check_existing = False
self.dynamo_force_manual_run = False
self.dynamo_model_nodes_info = None
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
mlogger.debug('Maximum host version: %s', self.max_revit_ver)
mlogger.debug('Minimum host version: %s', self.min_revit_ver)
mlogger.debug('command tooltip: %s', self._tooltip)
mlogger.debug('Command author: %s', self.author)
mlogger.debug('Command help url: %s', self._help_url)
if self.is_beta:
mlogger.debug('Command is in beta.')
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = None``instance-attribute` ##### `config_script_file = None``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `control_id``property` ##### `is_cpython``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | Back to top ## Revit Geometric Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/geom/#pyrevit.revit.geom) # geom Geometric utilities for Revit. ## Functions ### `convert_point_coord_system(rvt_point, rvt_transform)` Return coordinates of point in another coordinate system. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvt_point` | `XYZ` | Revit point | _required_ | | `rvt_transform` | `Transform` | Revit transform for target coord system | _required_ | Returns: | Type | Description | | --- | --- | | `XYZ` | Point coordinates in new coordinate system. | Source code in `pyrevitlib/pyrevit/revit/geom.py` | | | | --- | --- | | ```
6
7
8
9
10
11
12
13
14
15
16
17
18
``` | ```md-code__content
def convert_point_coord_system(rvt_point, rvt_transform):
"""Return coordinates of point in another coordinate system.
Args:
rvt_point (DB.XYZ): Revit point
rvt_transform (DB.Transform): Revit transform for target coord system
Returns:
(DB.XYZ): Point coordinates in new coordinate system.
"""
# transform the origin of the old coordinate system in the new
# coordinate system
return rvt_transform.OfVector(rvt_transform.Origin - rvt_point)
``` | ### `convert_point_to_metric(rvt_point)` Convert given point coordinates to metric. Source code in `pyrevitlib/pyrevit/revit/geom.py` | | | | --- | --- | | ```
21
22
23
24
25
``` | ```md-code__content
def convert_point_to_metric(rvt_point):
"""Convert given point coordinates to metric."""
return DB.XYZ(rvt_point.X * 0.3048,
rvt_point.Y * 0.3048,
rvt_point.Z * 0.3048)
``` | Back to top ## pyRevit Extension Components [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/components/#pyrevit.extensions.components) # components Base classes for pyRevit extension components. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `EXT_HASH_VALUE_KEY = 'dir_hash_value'``module-attribute` ### `EXT_HASH_VERSION_KEY = 'pyrvt_version'``module-attribute` ## Classes ### `NoButton(cmp_path=None, needs_script=True)` Bases: `GenericUICommand` This is not a button. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_script=True):
self.needs_script = needs_script
self.script_file = self.config_script_file = None
self.arguments = []
self.context = None
self.class_name = self.avail_class_name = None
self.requires_clean_engine = False
self.requires_fullframe_engine = False
self.requires_persistent_engine = False
self.requires_mainthread_engine = False
# engine options specific to dynamo
self.dynamo_path = None
# self.dynamo_path_exec = False
self.dynamo_path_check_existing = False
self.dynamo_force_manual_run = False
self.dynamo_model_nodes_info = None
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
mlogger.debug('Maximum host version: %s', self.max_revit_ver)
mlogger.debug('Minimum host version: %s', self.min_revit_ver)
mlogger.debug('command tooltip: %s', self._tooltip)
mlogger.debug('Command author: %s', self.author)
mlogger.debug('Command help url: %s', self._help_url)
if self.is_beta:
mlogger.debug('Command is in beta.')
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = None``instance-attribute` ##### `config_script_file = None``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.NOGUI_COMMAND_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ### `NoScriptButton(cmp_path=None, needs_commandclass=False)` Bases: `GenericUICommand` Base for buttons that doesn't run a script. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_commandclass=False):
# using classname otherwise exceptions in superclasses won't show
GenericUICommand.__init__(self, cmp_path=cmp_path, needs_script=False)
self.assembly = self.command_class = self.avail_command_class = None
# read metadata from metadata file
if self.meta:
# get the target assembly from metadata
self.assembly = \
self.meta.get(exts.MDATA_LINK_BUTTON_ASSEMBLY, None)
# get the target command class from metadata
self.command_class = \
self.meta.get(exts.MDATA_LINK_BUTTON_COMMAND_CLASS, None)
# get the target command class from metadata
self.avail_command_class = \
self.meta.get(exts.MDATA_LINK_BUTTON_AVAIL_COMMAND_CLASS, None)
# for invoke buttons there is no script source so
# assign the metadata file to the script
self.script_file = self.config_script_file = self.meta_file
else:
mlogger.debug("%s does not specify target assembly::class.", self)
if self.directory and not self.assembly:
mlogger.error("%s does not specify target assembly.", self)
if self.directory and needs_commandclass and not self.command_class:
mlogger.error("%s does not specify target command class.", self)
mlogger.debug('%s assembly.class: %s.%s',
self, self.assembly, self.command_class)
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `assembly = None``instance-attribute` ##### `command_class = None``instance-attribute` ##### `avail_command_class = None``instance-attribute` ##### `script_file = self.meta_file``instance-attribute` ##### `config_script_file = self.meta_file``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ##### `get_target_assembly(required=False)` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def get_target_assembly(self, required=False):
assm_file = self.assembly.lower()
if not assm_file.endswith(framework.ASSEMBLY_FILE_TYPE):
assm_file += '.' + framework.ASSEMBLY_FILE_TYPE
# try finding assembly for this specific host version
target_asm_by_host = self.find_bundle_module(assm_file, by_host=True)
if target_asm_by_host:
return target_asm_by_host
# try find assembly by its name
target_asm = self.find_bundle_module(assm_file)
if target_asm:
return target_asm
if required:
mlogger.error("%s can not find target assembly.", self)
return ''
``` | ### `LinkButton(cmp_path=None)` Bases: `NoScriptButton` Link button. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
NoScriptButton.__init__(
self,
cmp_path=cmp_path,
needs_commandclass=True
)
if self.context:
mlogger.warn(
"Linkbutton bundles do not support \"context:\". "
"Use \"availability_class:\" instead and specify name of "
"availability class in target assembly | %s", self
)
self.context = None
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = self.meta_file``instance-attribute` ##### `config_script_file = self.meta_file``instance-attribute` ##### `arguments = []``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `assembly = None``instance-attribute` ##### `command_class = None``instance-attribute` ##### `avail_command_class = None``instance-attribute` ##### `type_id = exts.LINK_BUTTON_POSTFIX``class-attribute``instance-attribute` ##### `context = None``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ##### `get_target_assembly(required=False)` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def get_target_assembly(self, required=False):
assm_file = self.assembly.lower()
if not assm_file.endswith(framework.ASSEMBLY_FILE_TYPE):
assm_file += '.' + framework.ASSEMBLY_FILE_TYPE
# try finding assembly for this specific host version
target_asm_by_host = self.find_bundle_module(assm_file, by_host=True)
if target_asm_by_host:
return target_asm_by_host
# try find assembly by its name
target_asm = self.find_bundle_module(assm_file)
if target_asm:
return target_asm
if required:
mlogger.error("%s can not find target assembly.", self)
return ''
``` | ### `InvokeButton(cmp_path=None)` Bases: `NoScriptButton` Invoke button. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
117
118
119
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
NoScriptButton.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = self.meta_file``instance-attribute` ##### `config_script_file = self.meta_file``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `assembly = None``instance-attribute` ##### `command_class = None``instance-attribute` ##### `avail_command_class = None``instance-attribute` ##### `type_id = exts.INVOKE_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ##### `get_target_assembly(required=False)` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def get_target_assembly(self, required=False):
assm_file = self.assembly.lower()
if not assm_file.endswith(framework.ASSEMBLY_FILE_TYPE):
assm_file += '.' + framework.ASSEMBLY_FILE_TYPE
# try finding assembly for this specific host version
target_asm_by_host = self.find_bundle_module(assm_file, by_host=True)
if target_asm_by_host:
return target_asm_by_host
# try find assembly by its name
target_asm = self.find_bundle_module(assm_file)
if target_asm:
return target_asm
if required:
mlogger.error("%s can not find target assembly.", self)
return ''
``` | ### `PushButton(cmp_path=None, needs_script=True)` Bases: `GenericUICommand` Push button. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_script=True):
self.needs_script = needs_script
self.script_file = self.config_script_file = None
self.arguments = []
self.context = None
self.class_name = self.avail_class_name = None
self.requires_clean_engine = False
self.requires_fullframe_engine = False
self.requires_persistent_engine = False
self.requires_mainthread_engine = False
# engine options specific to dynamo
self.dynamo_path = None
# self.dynamo_path_exec = False
self.dynamo_path_check_existing = False
self.dynamo_force_manual_run = False
self.dynamo_model_nodes_info = None
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
mlogger.debug('Maximum host version: %s', self.max_revit_ver)
mlogger.debug('Minimum host version: %s', self.min_revit_ver)
mlogger.debug('command tooltip: %s', self._tooltip)
mlogger.debug('Command author: %s', self.author)
mlogger.debug('Command help url: %s', self._help_url)
if self.is_beta:
mlogger.debug('Command is in beta.')
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = None``instance-attribute` ##### `config_script_file = None``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.PUSH_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ### `PanelPushButton(cmp_path=None, needs_script=True)` Bases: `GenericUICommand` Panel push button. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_script=True):
self.needs_script = needs_script
self.script_file = self.config_script_file = None
self.arguments = []
self.context = None
self.class_name = self.avail_class_name = None
self.requires_clean_engine = False
self.requires_fullframe_engine = False
self.requires_persistent_engine = False
self.requires_mainthread_engine = False
# engine options specific to dynamo
self.dynamo_path = None
# self.dynamo_path_exec = False
self.dynamo_path_check_existing = False
self.dynamo_force_manual_run = False
self.dynamo_model_nodes_info = None
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
mlogger.debug('Maximum host version: %s', self.max_revit_ver)
mlogger.debug('Minimum host version: %s', self.min_revit_ver)
mlogger.debug('command tooltip: %s', self._tooltip)
mlogger.debug('Command author: %s', self.author)
mlogger.debug('Command help url: %s', self._help_url)
if self.is_beta:
mlogger.debug('Command is in beta.')
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = None``instance-attribute` ##### `config_script_file = None``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.PANEL_PUSH_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ### `SmartButton(cmp_path=None, needs_script=True)` Bases: `GenericUICommand` Smart button. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
``` | ```md-code__content
def __init__(self, cmp_path=None, needs_script=True):
self.needs_script = needs_script
self.script_file = self.config_script_file = None
self.arguments = []
self.context = None
self.class_name = self.avail_class_name = None
self.requires_clean_engine = False
self.requires_fullframe_engine = False
self.requires_persistent_engine = False
self.requires_mainthread_engine = False
# engine options specific to dynamo
self.dynamo_path = None
# self.dynamo_path_exec = False
self.dynamo_path_check_existing = False
self.dynamo_force_manual_run = False
self.dynamo_model_nodes_info = None
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
mlogger.debug('Maximum host version: %s', self.max_revit_ver)
mlogger.debug('Minimum host version: %s', self.min_revit_ver)
mlogger.debug('command tooltip: %s', self._tooltip)
mlogger.debug('Command author: %s', self.author)
mlogger.debug('Command help url: %s', self._help_url)
if self.is_beta:
mlogger.debug('Command is in beta.')
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `script_file = None``instance-attribute` ##### `config_script_file = None``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.SMART_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ### `ContentButton(cmp_path=None)` Bases: `GenericUICommand` Content Button. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
GenericUICommand.__init__(
self,
cmp_path=cmp_path,
needs_script=False
)
# find content file
self.script_file = \
self.find_bundle_file([
exts.CONTENT_VERSION_POSTFIX.format(
version=HOST_APP.version
),
])
if not self.script_file:
self.script_file = \
self.find_bundle_file([
exts.CONTENT_POSTFIX,
])
# requires at least one bundles
if self.directory and not self.script_file:
mlogger.error('Command %s: Does not have content file.', self)
self.script_file = ''
# find alternative content file
self.config_script_file = \
self.find_bundle_file([
exts.ALT_CONTENT_VERSION_POSTFIX.format(
version=HOST_APP.version
),
])
if not self.config_script_file:
self.config_script_file = \
self.find_bundle_file([
exts.ALT_CONTENT_POSTFIX,
])
if not self.config_script_file:
self.config_script_file = self.script_file
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.CONTENT_BUTTON_POSTFIX``class-attribute``instance-attribute` ##### `script_file = self.find_bundle_file([exts.CONTENT_VERSION_POSTFIX.format(version=HOST_APP.version)])``instance-attribute` ##### `config_script_file = self.find_bundle_file([exts.ALT_CONTENT_VERSION_POSTFIX.format(version=HOST_APP.version)])``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ### `URLButton(cmp_path=None)` Bases: `GenericUICommand` URL button. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
GenericUICommand.__init__(self, cmp_path=cmp_path, needs_script=False)
self.target_url = None
# read metadata from metadata file
if self.meta:
# get the target url from metadata
self.target_url = \
self.meta.get(exts.MDATA_URL_BUTTON_HYPERLINK, None)
# for url buttons there is no script source so
# assign the metadata file to the script
self.script_file = self.config_script_file = self.meta_file
else:
mlogger.debug("%s does not specify target assembly::class.", self)
if self.directory and not self.target_url:
mlogger.error("%s does not specify target url.", self)
mlogger.debug('%s target url: %s', self, self.target_url)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `needs_script = needs_script``instance-attribute` ##### `arguments = []``instance-attribute` ##### `context = None``instance-attribute` ##### `class_name = None``instance-attribute` ##### `avail_class_name = None``instance-attribute` ##### `requires_clean_engine = False``instance-attribute` ##### `requires_fullframe_engine = False``instance-attribute` ##### `requires_persistent_engine = False``instance-attribute` ##### `requires_mainthread_engine = False``instance-attribute` ##### `dynamo_path = None``instance-attribute` ##### `dynamo_path_check_existing = False``instance-attribute` ##### `dynamo_force_manual_run = False``instance-attribute` ##### `dynamo_model_nodes_info = None``instance-attribute` ##### `script_language``property` ##### `is_cpython``property` ##### `type_id = exts.URL_BUTTON_POSTFIX``class-attribute``instance-attribute` ##### `target_url = None``instance-attribute` ##### `script_file = self.meta_file``instance-attribute` ##### `config_script_file = self.meta_file``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
276
277
278
279
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
281
282
283
284
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
327
328
329
330
331
332
333
334
335
336
337
338
``` | ```md-code__content
def configure(self, config_dict):
configurable_params = \
['_ui_title', '_tooltip', '_help_url', 'author']
# get root key:value pairs
for key, value in config_dict.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
# get key:value pairs grouped under special key, if exists
templates = config_dict.get(exts.MDATA_TEMPLATES_KEY, {})
for key, value in templates.items():
for param_name in configurable_params:
self._resolve_liquid_tag(param_name, key, value)
``` | ##### `has_config_script()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
819
820
``` | ```md-code__content
def has_config_script(self):
return self.config_script_file != self.script_file
``` | ##### `get_target_url()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
205
206
``` | ```md-code__content
def get_target_url(self):
return self.target_url or ""
``` | ### `GenericUICommandGroup(cmp_path=None)` Bases: `GenericUIContainer` Generic UI command group. Command groups only include commands. These classes can include GenericUICommand as sub components. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `type_id = None``class-attribute``instance-attribute` ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `allowed_sub_cmps = [GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `control_id``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
229
230
231
232
``` | ```md-code__content
def has_commands(self):
for component in self:
if isinstance(component, GenericUICommand):
return True
``` | ### `PullDownButtonGroup(cmp_path=None)` Bases: `GenericUICommandGroup` Pulldown button group. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `allowed_sub_cmps = [GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.PULLDOWN_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
229
230
231
232
``` | ```md-code__content
def has_commands(self):
for component in self:
if isinstance(component, GenericUICommand):
return True
``` | ### `SplitPushButtonGroup(cmp_path=None)` Bases: `GenericUICommandGroup` Split push button group. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `allowed_sub_cmps = [GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.SPLITPUSH_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
229
230
231
232
``` | ```md-code__content
def has_commands(self):
for component in self:
if isinstance(component, GenericUICommand):
return True
``` | ### `SplitButtonGroup(cmp_path=None)` Bases: `GenericUICommandGroup` Split button group. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `allowed_sub_cmps = [GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.SPLIT_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
229
230
231
232
``` | ```md-code__content
def has_commands(self):
for component in self:
if isinstance(component, GenericUICommand):
return True
``` | ### `GenericStack(cmp_path=None)` Bases: `GenericUIContainer` Generic UI stack. Stacks include GenericUICommand, or GenericUICommandGroup. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.STACK_BUTTON_POSTFIX``class-attribute``instance-attribute` ##### `allowed_sub_cmps = [GenericUICommandGroup, GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `control_id``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
265
266
267
268
269
270
271
272
``` | ```md-code__content
def has_commands(self):
for component in self:
if not component.is_container:
if isinstance(component, GenericUICommand):
return True
else:
if component.has_commands():
return True
``` | ### `StackButtonGroup(cmp_path=None)` Bases: `GenericStack` Stack buttons group. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `allowed_sub_cmps = [GenericUICommandGroup, GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.STACK_BUTTON_POSTFIX``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
265
266
267
268
269
270
271
272
``` | ```md-code__content
def has_commands(self):
for component in self:
if not component.is_container:
if isinstance(component, GenericUICommand):
return True
else:
if component.has_commands():
return True
``` | ### `Panel(cmp_path=None)` Bases: `GenericUIContainer` Panel container. Panels include GenericStack, GenericUICommand, or GenericUICommandGroup Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
GenericUIContainer.__init__(self, cmp_path=cmp_path)
self.panel_background = \
self.title_background = \
self.slideout_background = None
# read metadata from metadata file
if self.meta:
# check for background color configs
self.panel_background = \
self.meta.get(exts.MDATA_BACKGROUND_KEY, None)
if self.panel_background:
if isinstance(self.panel_background, dict):
self.title_background = self.panel_background.get(
exts.MDATA_BACKGROUND_TITLE_KEY, None)
self.slideout_background = self.panel_background.get(
exts.MDATA_BACKGROUND_SLIDEOUT_KEY, None)
self.panel_background = self.panel_background.get(
exts.MDATA_BACKGROUND_PANEL_KEY, None)
elif not isinstance(self.panel_background, str):
mlogger.error(
"%s bad background definition in metadata.", self)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.PANEL_POSTFIX``class-attribute``instance-attribute` ##### `allowed_sub_cmps = [GenericStack, GenericUICommandGroup, GenericUICommand, NoScriptButton]``class-attribute``instance-attribute` ##### `panel_background = None``instance-attribute` ##### `title_background = None``instance-attribute` ##### `slideout_background = None``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
312
313
314
315
316
317
318
319
``` | ```md-code__content
def has_commands(self):
for component in self:
if not component.is_container:
if isinstance(component, GenericUICommand):
return True
else:
if component.has_commands():
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
``` | ```md-code__content
def contains(self, item_name):
# Panels contain stacks. But stacks itself does not have any ui and its
# subitems are displayed within the ui of the parent panel.
# This is different from pulldowns and other button groups.
# Button groups, contain and display their sub components in their
# own drop down menu. So when checking if panel has a button,
# panel should check all the items visible to the user and respond.
item_exists = GenericUIContainer.contains(self, item_name)
if item_exists:
return True
else:
# if child is a stack item, check its children too
for component in self:
if isinstance(component, GenericStack) \
and component.contains(item_name):
return True
``` | ### `Tab(cmp_path=None)` Bases: `GenericUIContainer` Tab container for Panels. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
345
346
347
348
349
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.layout_items = []
self.components = []
# using classname otherwise exceptions in superclasses won't show
GenericUIComponent.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `control_id``property` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.TAB_POSTFIX``class-attribute``instance-attribute` ##### `allowed_sub_cmps = [Panel]``class-attribute``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `configure(config_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
``` | ```md-code__content
def configure(self, config_dict):
# update self meta
GenericUIComponent.configure(self, config_dict=config_dict)
# create an updated dict to pass to children
updated_dict = copy.deepcopy(config_dict)
updated_dict = pyutils.merge(updated_dict, self.meta)
# replace the meta values with the expanded values
# so children can use the expanded
updated_dict[exts.MDATA_UI_TITLE] = self.ui_title
updated_dict[exts.MDATA_TOOLTIP] = self.tooltip
updated_dict[exts.MDATA_COMMAND_HELP_URL] = self.help_url
updated_dict[exts.AUTHOR_PARAM] = self.author
if exts.AUTHORS_PARAM in updated_dict:
updated_dict.pop(exts.AUTHORS_PARAM)
for component in self:
component.configure(updated_dict)
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `has_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
344
345
346
347
348
``` | ```md-code__content
def has_commands(self):
for panel in self:
if panel.has_commands():
return True
return False
``` | ### `Extension(cmp_path=None)` Bases: `GenericUIContainer` UI Tools extension. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
356
357
358
359
360
``` | ```md-code__content
def __init__(self, cmp_path=None):
self.pyrvt_version = None
self.dir_hash_value = None
# using classname otherwise exceptions in superclasses won't show
GenericUIContainer.__init__(self, cmp_path=cmp_path)
``` | #### Attributes ##### `name = None``instance-attribute` ##### `is_container``property` ##### `directory = cmp_path``instance-attribute` ##### `unique_name = None``instance-attribute` ##### `parent_ctrl_id = None``instance-attribute` ##### `icon_file = None``instance-attribute` ##### `author = None``instance-attribute` ##### `media_file = None``instance-attribute` ##### `min_revit_ver = None``instance-attribute` ##### `max_revit_ver = None``instance-attribute` ##### `is_beta = False``instance-attribute` ##### `highlight_type = None``instance-attribute` ##### `collapsed = False``instance-attribute` ##### `version = None``instance-attribute` ##### `meta = {}``instance-attribute` ##### `meta_file = None``instance-attribute` ##### `modules = []``instance-attribute` ##### `module_paths = []``instance-attribute` ##### `binary_path = None``instance-attribute` ##### `library_path = None``instance-attribute` ##### `ui_title``property` ##### `tooltip``property` ##### `help_url``property` ##### `is_supported``property` ##### `layout_items = []``instance-attribute` ##### `components = []``instance-attribute` ##### `type_id = exts.ExtensionTypes.UI_EXTENSION.POSTFIX``class-attribute``instance-attribute` ##### `allowed_sub_cmps = [Tab]``class-attribute``instance-attribute` ##### `pyrvt_version = None``instance-attribute` ##### `dir_hash_value = None``instance-attribute` ##### `control_id``property` ##### `startup_script``property` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
104
105
106
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ##### `make_unique_name(cmp_path)``classmethod` Creates a unique name for the command. This is used to uniquely identify this command and also to create the class in pyRevit dll assembly. Current method create a unique name based on the command full directory address. Examples: for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton' unique name would be: 'pyrevit-pyrevit-edit-flipdoors'. Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
``` | ```md-code__content
@classmethod
def make_unique_name(cls, cmp_path):
"""Creates a unique name for the command.
This is used to uniquely identify this command
and also to create the class in pyRevit dll assembly.
Current method create a unique name based on the command
full directory address.
Examples:
for 'pyRevit.extension/pyRevit.tab/Edit.panel/Flip doors.pushbutton'
unique name would be: 'pyrevit-pyrevit-edit-flipdoors'.
"""
pieces = []
inside_ext = False
for dname in cmp_path.split(op.sep):
if exts.ExtensionTypes.UI_EXTENSION.POSTFIX in dname:
inside_ext = True
name, ext = op.splitext(dname)
if ext != '' and inside_ext:
pieces.append(name)
else:
continue
return coreutils.cleanup_string(
exts.UNIQUE_ID_SEPARATOR.join(pieces),
skip=[exts.UNIQUE_ID_SEPARATOR]
).lower()
``` | ##### `get_full_bundle_name()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
270
271
``` | ```md-code__content
def get_full_bundle_name(self):
return self.name + self.type_id
``` | ##### `has_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
273
274
``` | ```md-code__content
def has_module_path(self, path):
return path in self.module_paths
``` | ##### `add_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
445
446
447
448
449
450
``` | ```md-code__content
def add_module_path(self, path):
if path and not self.has_module_path(path):
mlogger.debug('Appending syspath: %s to %s', path, self)
for component in self.components:
component.add_module_path(path)
self.module_paths.append(path)
``` | ##### `remove_module_path(path)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
452
453
454
455
456
457
``` | ```md-code__content
def remove_module_path(self, path):
if path and self.has_module_path(path):
mlogger.debug('Removing syspath: %s from %s', path, self)
for component in self.components:
component.remove_module_path(path)
return self.module_paths.remove(path)
``` | ##### `get_bundle_file(file_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
286
287
288
289
``` | ```md-code__content
def get_bundle_file(self, file_name):
if self.directory and file_name:
file_addr = op.join(self.directory, file_name)
return file_addr if op.exists(file_addr) else None
``` | ##### `find_bundle_file(patterns, finder='postfix')` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
``` | ```md-code__content
def find_bundle_file(self, patterns, finder='postfix'):
if self.directory:
for bundle_file in os.listdir(self.directory):
if 'name' == finder:
for file_name in patterns:
if op.splitext(bundle_file)[0] == file_name:
return op.join(self.directory, bundle_file)
elif 'postfix' == finder:
for file_postfix in patterns:
if bundle_file.endswith(file_postfix):
return op.join(self.directory, bundle_file)
elif 'regex' == finder:
for regex_pattern in patterns:
if re.match(regex_pattern, bundle_file):
return op.join(self.directory, bundle_file)
return None
``` | ##### `find_bundle_module(module, by_host=False)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
``` | ```md-code__content
def find_bundle_module(self, module, by_host=False):
# test of file_name is an actually path to a file
if op.isfile(module):
return module
def build_assm_filename(module_filename):
# build assembly by host version (assm_file_2020.ext)
assm_name, assm_ext = op.splitext(module_filename)
return assm_name + '_' + HOST_APP.version + assm_ext
if by_host:
module = build_assm_filename(module)
# test if module is inside search paths
for module_path in self.module_paths:
possible_module_path = op.join(module_path, module)
if op.isfile(possible_module_path):
return possible_module_path
``` | ##### `parse_layout_directive(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
``` | ```md-code__content
def parse_layout_directive(self, layout_line):
parts = re.findall(r'(.+)\[(.+):(.*)\]', layout_line)
if parts:
source_item, directive, target_value = parts[0]
# cleanup values
directive = directive.lower().strip()
target_value = target_value.strip()
# process any escape characters in target value
# https://stackoverflow.com/a/4020824/2350244
target_value = target_value.encode('utf-8')
if PY3:
target_value = target_value.decode('unicode_escape')
else:
target_value = target_value.decode('string_escape')
# create directive obj
return source_item, LayoutDirective(directive_type=directive,
target=target_value)
return layout_line, None
``` | ##### `parse_layout_item(layout_line)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
422
423
424
425
426
427
``` | ```md-code__content
def parse_layout_item(self, layout_line):
if layout_line:
layout_item_name, layout_item_drctv = \
self.parse_layout_directive(layout_line)
return LayoutItem(name=layout_item_name,
directive=layout_item_drctv)
``` | ##### `parse_layout_items(layout_lines)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
429
430
431
432
433
434
``` | ```md-code__content
def parse_layout_items(self, layout_lines):
for layout_line in layout_lines:
layout_item = self.parse_layout_item(layout_line)
if layout_item:
self.layout_items.append(layout_item)
mlogger.debug('Layout is: %s', self.layout_items)
``` | ##### `parse_layout_metadata()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
436
437
438
439
440
``` | ```md-code__content
def parse_layout_metadata(self):
layout = self.meta.get(exts.MDATA_LAYOUT, [])
if layout:
self.parse_layout_items(layout)
return True
``` | ##### `contains(item_name)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
442
443
``` | ```md-code__content
def contains(self, item_name):
return any([x.name == item_name for x in self.components])
``` | ##### `add_component(comp)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
459
460
461
462
463
464
465
466
467
``` | ```md-code__content
def add_component(self, comp):
# set search paths
for path in self.module_paths:
comp.add_module_path(path)
# set its own control id on the child component
if hasattr(comp, 'parent_ctrl_id'):
comp.parent_ctrl_id = self.control_id
# now add to list
self.components.append(comp)
``` | ##### `find_components_of_type(cmp_type)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def find_components_of_type(self, cmp_type):
sub_comp_list = []
for sub_comp in self.components:
if isinstance(sub_comp, cmp_type):
sub_comp_list.append(sub_comp)
elif sub_comp.is_container:
sub_comp_list.extend(sub_comp.find_components_of_type(cmp_type))
return sub_comp_list
``` | ##### `find_layout_items()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
479
480
481
482
483
484
485
``` | ```md-code__content
def find_layout_items(self):
layout_items = []
layout_items.extend(self.layout_items)
for sub_comp in self.components:
if sub_comp.is_container:
layout_items.extend(sub_comp.find_layout_items())
return layout_items
``` | ##### `get_hash()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
427
428
``` | ```md-code__content
def get_hash(self):
return coreutils.get_str_hash(safe_strtype(self.get_cache_data()))
``` | ##### `get_all_commands()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
430
431
``` | ```md-code__content
def get_all_commands(self):
return self.find_components_of_type(GenericUICommand)
``` | ##### `get_manifest_file()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
433
434
``` | ```md-code__content
def get_manifest_file(self):
return self.get_bundle_file(exts.EXT_MANIFEST_FILE)
``` | ##### `get_manifest()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
def get_manifest(self):
manifest_file = self.get_manifest_file()
if manifest_file:
with codecs.open(manifest_file, 'r', 'utf-8') as mfile:
try:
manifest_cfg = json.load(mfile)
return manifest_cfg
except Exception as manfload_err:
print('Can not parse ext manifest file: {} '
'| {}'.format(manifest_file, manfload_err))
return
``` | ##### `configure()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
448
449
450
451
452
``` | ```md-code__content
def configure(self):
cfg_dict = self.get_manifest()
if cfg_dict:
for component in self:
component.configure(cfg_dict)
``` | ##### `get_extension_modules()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
454
455
456
457
458
459
460
461
462
463
``` | ```md-code__content
def get_extension_modules(self):
modules = []
if self.binary_path and op.exists(self.binary_path):
for item in os.listdir(self.binary_path):
item_path = op.join(self.binary_path, item)
item_name = item.lower()
if op.isfile(item_path) \
and item_name.endswith(framework.ASSEMBLY_FILE_TYPE):
modules.append(item_path)
return modules
``` | ##### `get_command_modules()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
465
466
467
468
469
470
471
472
``` | ```md-code__content
def get_command_modules(self):
referenced_modules = set()
for cmd in self.get_all_commands():
for module in cmd.modules:
cmd_module = cmd.find_bundle_module(module)
if cmd_module:
referenced_modules.add(cmd_module)
return referenced_modules
``` | ##### `get_hooks()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
474
475
476
``` | ```md-code__content
def get_hooks(self):
hook_scripts = os.listdir(self.hooks_path) if self.hooks_path else []
return [op.join(self.hooks_path, x) for x in hook_scripts]
``` | ##### `get_checks()` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
478
479
480
``` | ```md-code__content
def get_checks(self):
check_scripts = os.listdir(self.checks_path) if self.checks_path else []
return [op.join(self.checks_path, x) for x in check_scripts]
``` | ### `LibraryExtension(cmp_path=None)` Bases: `GenericComponent` Library extension. Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
487
488
489
490
491
492
493
``` | ```md-code__content
def __init__(self, cmp_path=None):
# using classname otherwise exceptions in superclasses won't show
GenericComponent.__init__(self)
self.directory = cmp_path
if self.directory:
self.name = op.splitext(op.basename(self.directory))[0]
``` | #### Attributes ##### `is_container``property` ##### `type_id = exts.ExtensionTypes.LIB_EXTENSION.POSTFIX``class-attribute``instance-attribute` ##### `directory = cmp_path``instance-attribute` ##### `name = op.splitext(op.basename(self.directory))[0]``instance-attribute` #### Functions ##### `get_cache_data()` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def get_cache_data(self):
cache_dict = self.__dict__.copy()
if hasattr(self, TYPE_ID_KEY):
cache_dict[TYPE_ID_KEY] = getattr(self, TYPE_ID_KEY)
return cache_dict
``` | ##### `load_cache_data(cache_dict)` Source code in `pyrevitlib/pyrevit/extensions/genericcomps.py` | | | | --- | --- | | ```
43
44
45
``` | ```md-code__content
def load_cache_data(self, cache_dict):
for k, v in cache_dict.items():
self.__dict__[k] = v
``` | ##### `matches(component_path)``classmethod` Source code in `pyrevitlib/pyrevit/extensions/components.py` | | | | --- | --- | | ```
499
500
501
``` | ```md-code__content
@classmethod
def matches(cls, component_path):
return component_path.lower().endswith(cls.type_id)
``` | ## Functions Back to top ## Revit Features Detection [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/features/#pyrevit.revit.features) # features Host application feature detectors. ## Attributes ### `GLOBAL_PARAMS = hasattr(DB, 'GlobalParametersManager')``module-attribute` Back to top ## Smart Module Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/moduleutils/#pyrevit.coreutils.moduleutils) # moduleutils Utility fuctions to support smart modules. ## Functions ### `copy_func(func, func_name, doc_string=None, arg_list=None)` Copy a function object to create a new function. This is used inside smart modules that auto-generate functions based on context. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `func` | `object` | python source function object | _required_ | | `func_name` | `str` | new function name | _required_ | | `doc_string` | `str` | new function docstring | `None` | | `arg_list` | `list` | list of default values for function arguments | `None` | Returns: | Type | Description | | --- | --- | | `object` | new python function objects | Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
``` | ```md-code__content
def copy_func(func, func_name, doc_string=None, arg_list=None):
"""Copy a function object to create a new function.
This is used inside smart modules that auto-generate functions based on
context.
Args:
func (object): python source function object
func_name (str): new function name
doc_string (str): new function docstring
arg_list (list): list of default values for function arguments
Returns:
(object): new python function objects
"""
new_func = types.FunctionType(func.func_code, func.func_globals,
func_name, tuple(arg_list), func.func_closure)
new_func.__doc__ = doc_string
return new_func
``` | ### `mark(prop_name)` Decorator function to add a marker property to the given type. Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
27
28
29
30
31
32
``` | ```md-code__content
def mark(prop_name):
"""Decorator function to add a marker property to the given type."""
def setter_decorator(type_obj):
setattr(type_obj, prop_name, True)
return type_obj
return setter_decorator
``` | ### `collect_marked(module_obj, prop_name)` Collect module objects that are marked with given property. Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
35
36
37
38
39
40
41
42
43
``` | ```md-code__content
def collect_marked(module_obj, prop_name):
"""Collect module objects that are marked with given property."""
marked_objs = []
for member in inspect.getmembers(module_obj):
_, type_obj = member
if (inspect.isclass(type_obj) or inspect.isfunction(type_obj)) \
and getattr(type_obj, prop_name, False):
marked_objs.append(type_obj)
return marked_objs
``` | ### `has_argument(function_obj, arg_name)` Check if given function object has argument matching arg\_name. Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
46
47
48
``` | ```md-code__content
def has_argument(function_obj, arg_name):
"""Check if given function object has argument matching arg_name."""
return arg_name in inspect.getargspec(function_obj)[0] #pylint: disable=deprecated-method
``` | ### `has_any_arguments(function_obj, arg_name_list)` Check if given function object has any of given arguments. Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
51
52
53
54
55
56
``` | ```md-code__content
def has_any_arguments(function_obj, arg_name_list):
"""Check if given function object has any of given arguments."""
args = inspect.getargspec(function_obj)[0] #pylint: disable=deprecated-method
if arg_name_list:
return any(x in args for x in arg_name_list)
return False
``` | ### `filter_kwargs(function_obj, kwargs)` Filter given arguments dict for function\_obj arguments. Source code in `pyrevitlib/pyrevit/coreutils/moduleutils.py` | | | | --- | --- | | ```
59
60
61
62
63
64
``` | ```md-code__content
def filter_kwargs(function_obj, kwargs):
"""Filter given arguments dict for function_obj arguments."""
filtered_kwargs = {}
for arg_name in inspect.getargspec(function_obj)[0]: #pylint: disable=deprecated-method
filtered_kwargs[arg_name] = kwargs.get(arg_name, None)
return filtered_kwargs
``` | Back to top ## Revit UI Functions [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/ui/#pyrevit.revit.ui) # ui UI functions. ## Attributes ## Functions ### `get_mainwindow_hwnd()` Get the handle of the main window. Returns: | Type | Description | | --- | --- | | `intptr` | The handle of the main window. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
21
22
23
24
25
26
27
``` | ```md-code__content
def get_mainwindow_hwnd():
"""Get the handle of the main window.
Returns:
(intptr): The handle of the main window.
"""
return HOST_APP.proc_window
``` | ### `get_mainwindow()` Get the main window of the application. Returns: | Type | Description | | --- | --- | | `MainWindow` | The root visual of the main window. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
30
31
32
33
34
35
36
37
38
39
40
``` | ```md-code__content
def get_mainwindow():
"""Get the main window of the application.
Returns:
(MainWindow): The root visual of the main window.
"""
try:
hwnd_source = Interop.HwndSource.FromHwnd(HOST_APP.proc_window)
return hwnd_source.RootVisual
except Exception:
pass
``` | ### `get_statusbar_hwnd()` Retrieves the handle of the status bar control belonging to the main window. Returns: | Type | Description | | --- | --- | | `IntPtr` | The handle of the status bar control. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
43
44
45
46
47
48
49
50
51
52
53
``` | ```md-code__content
def get_statusbar_hwnd():
"""Retrieves the handle of the status bar control belonging to the main window.
Returns:
(IntPtr): The handle of the status bar control.
"""
return Common.User32.FindWindowEx(
get_mainwindow_hwnd(),
IntPtr.Zero,
"msctls_statusbar32",
"")
``` | ### `set_statusbar_text(text)` Sets the text of the status bar. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `text` | `str` | The text to be displayed in the status bar. | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True if the text was successfully set, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
``` | ```md-code__content
def set_statusbar_text(text):
"""Sets the text of the status bar.
Parameters:
text (str): The text to be displayed in the status bar.
Returns:
(bool): True if the text was successfully set, False otherwise.
"""
status_bar_ptr = get_statusbar_hwnd()
if status_bar_ptr != IntPtr.Zero:
Common.User32.SetWindowText(status_bar_ptr, text)
return True
return False
``` | ### `get_window_rectangle()` Get the rectangle coordinates of the main window. Returns: | Type | Description | | --- | --- | | `Tuple[int, int, int, int]` | The left, top, right, and bottom
coordinates of the window rectangle. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
74
75
76
77
78
79
80
81
``` | ```md-code__content
def get_window_rectangle():
"""Get the rectangle coordinates of the main window.
Returns:
(Tuple[int, int, int, int]): The left, top, right, and bottom
coordinates of the window rectangle.
"""
return Common.User32.GetWindowRect(get_mainwindow_hwnd())
``` | ### `is_infocenter_visible()` Check if the InfoCenter toolbar is visible. Returns: | Type | Description | | --- | --- | | `bool` | True if the InfoCenter toolbar is visible, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
84
85
86
87
88
89
90
91
``` | ```md-code__content
def is_infocenter_visible():
"""Check if the InfoCenter toolbar is visible.
Returns:
(bool): True if the InfoCenter toolbar is visible, False otherwise.
"""
return ad.ComponentManager.InfoCenterToolBar.Visibility == \
Windows.Visibility.Visible
``` | ### `toggle_infocenter()` Toggles the visibility of the InfoCenter toolbar. This function retrieves the current visibility state of the InfoCenter toolbar and toggles it to the opposite state. If the toolbar is currently collapsed, it will be set to visible, and if it is currently visible, it will be set to collapsed. The function then returns the visibility state of the InfoCenter toolbar after the toggle operation. Returns: | Type | Description | | --- | --- | | `bool` | True if the InfoCenter toolbar is visible, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
``` | ```md-code__content
def toggle_infocenter():
"""Toggles the visibility of the InfoCenter toolbar.
This function retrieves the current visibility state of the InfoCenter
toolbar and toggles it to the opposite state.
If the toolbar is currently collapsed, it will be set to visible,
and if it is currently visible, it will be set to collapsed.
The function then returns the visibility state of the InfoCenter toolbar
after the toggle operation.
Returns:
(bool): True if the InfoCenter toolbar is visible, False otherwise.
"""
current_state = ad.ComponentManager.InfoCenterToolBar.Visibility
is_hidden = (current_state == Windows.Visibility.Collapsed)
ad.ComponentManager.InfoCenterToolBar.Visibility = \
Windows.Visibility.Visible if is_hidden else \
Windows.Visibility.Collapsed
return is_infocenter_visible()
``` | ### `get_ribbon_roottype()` Get the type of the ribbon root. Returns: | Type | Description | | --- | --- | | `type` | type of the ribbon root | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
115
116
117
118
119
120
121
122
123
124
``` | ```md-code__content
def get_ribbon_roottype():
"""Get the type of the ribbon root.
Returns:
(type): type of the ribbon root
"""
ap_assm = clr.GetClrType(ap.Windows.RibbonTabList).Assembly
for apt in ap_assm.GetTypes():
if 'PanelSetListView' in apt.Name:
return apt
``` | ### `get_current_theme()` Get the current UI theme. Returns: | Name | Type | Description | | --- | --- | --- | | `UITheme` | `UITheme` | The current UI theme. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
127
128
129
130
131
132
133
``` | ```md-code__content
def get_current_theme():
"""Get the current UI theme.
Returns:
UITheme (UITheme): The current UI theme.
"""
return UIThemeManager.CurrentTheme
``` | ### `set_current_theme(theme='Dark')` Sets the current UI theme to either 'Dark' or 'Light'. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `theme` | `str` | The theme to set. Defaults to 'Dark'. | `'Dark'` | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
136
137
138
139
140
141
142
143
144
145
``` | ```md-code__content
def set_current_theme(theme='Dark'):
"""Sets the current UI theme to either 'Dark' or 'Light'.
Args:
theme (str, optional): The theme to set. Defaults to 'Dark'.
"""
if theme == 'Dark':
UIThemeManager.CurrentTheme = UITheme.Dark
else:
UIThemeManager.CurrentTheme = UITheme.Light
``` | ### `resolve_icon_file(directory, icon_name)` Resolves the icon file path based on the current UI theme. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `directory` | `str` | The directory where the icon file is located. | _required_ | | `icon_name` | `str` | The name of the icon file. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `full_file_path` | `str` | The full file path of the icon file. | Source code in `pyrevitlib/pyrevit/revit/ui.py` | | | | --- | --- | | ```
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
``` | ```md-code__content
def resolve_icon_file(directory, icon_name):
"""Resolves the icon file path based on the current UI theme.
Args:
directory (str): The directory where the icon file is located.
icon_name (str): The name of the icon file.
Returns:
full_file_path (str): The full file path of the icon file.
"""
full_file_path = op.join(directory, icon_name)
if HOST_APP.is_newer_than(2024, True) and get_current_theme() == UITheme.Dark:
dark_icon_name = op.splitext(icon_name)[0] + ICON_DARK_SUFFIX + ICON_FILE_FORMAT
dark_file_path = op.join(directory, dark_icon_name)
full_file_path = dark_file_path if op.exists(dark_file_path) else full_file_path
return full_file_path if op.exists(full_file_path) else None
``` | Back to top ## Revit Reporting Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/report/#pyrevit.revit.report) # report "Utility methods for reporting Revit data uniformly. ## Classes ## Functions ### `print_revision(rev, prefix='', print_id=True)` Print a revision. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rev` | `Revision` | revision to output | _required_ | | `prefix` | `str` | prefix to add to the output text. Defaults to empty string. | `''` | | `print_id` | `bool` | whether to print the revision id. Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/revit/report.py` | | | | --- | --- | | ```
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
``` | ```md-code__content
def print_revision(rev, prefix='', print_id=True):
"""Print a revision.
Args:
rev (DB.Revision): revision to output
prefix (str, optional): prefix to add to the output text. Defaults to empty string.
print_id (bool, optional): whether to print the revision id. Defaults to True.
"""
outstr = 'SEQ#: {} REV#: {} DATE: {} TYPE: {} DESC: {} ' \
.format(rev.SequenceNumber,
str(query.get_param(rev, 'RevisionNumber', '')).ljust(5),
str(rev.RevisionDate).ljust(10),
str(rev.NumberType if rev.NumberType else "").ljust(15),
str(rev.Description).replace('\n', '').replace('\r', ''))
if print_id:
outstr = PyRevitOutputWindow.linkify(rev.Id) + '\t' + outstr
print(prefix + outstr)
``` | ### `print_sheet(sht, prefix='', print_id=True)` Print the name of a sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sht` | `ViewSheet` | sheet to output | _required_ | | `prefix` | `str` | prefix to add to the output text. Defaults to empty string. | `''` | | `print_id` | `bool` | whether to print the sheet id. Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/revit/report.py` | | | | --- | --- | | ```
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
``` | ```md-code__content
def print_sheet(sht, prefix='', print_id=True):
"""Print the name of a sheet.
Args:
sht (DB.ViewSheet): sheet to output
prefix (str, optional): prefix to add to the output text. Defaults to empty string.
print_id (bool, optional): whether to print the sheet id. Defaults to True.
"""
outstr = '{}\t{}'.format(
sht.Parameter[DB.BuiltInParameter.SHEET_NUMBER].AsString(),
sht.Parameter[DB.BuiltInParameter.SHEET_NAME].AsString()
)
if print_id:
outstr = PyRevitOutputWindow.linkify(sht.Id) + '\t' + outstr
print(prefix + outstr)
``` | ### `print_view(view, prefix='', print_id=True)` Print the name of a view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | view to output | _required_ | | `prefix` | `str` | prefix to add to the output text. Defaults to empty string. | `''` | | `print_id` | `bool` | whether to print the view id. Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/revit/report.py` | | | | --- | --- | | ```
44
45
46
47
48
49
50
51
52
53
54
55
``` | ```md-code__content
def print_view(view, prefix='', print_id=True):
"""Print the name of a view.
Args:
view (DB.View): view to output
prefix (str, optional): prefix to add to the output text. Defaults to empty string.
print_id (bool, optional): whether to print the view id. Defaults to True.
"""
outstr = query.get_name(view)
if print_id:
outstr = PyRevitOutputWindow.linkify(view.Id) + '\t' + outstr
print(prefix + outstr)
``` | Back to top ## Revit Tab Colorizer API [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/tabs/#pyrevit.revit.tabs) # tabs Document colorizer python API. ## Attributes ## Functions ### `hex_to_brush(color_hex)` Convert hex color to WPF brush. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
11
12
13
14
15
``` | ```md-code__content
def hex_to_brush(color_hex):
"""Convert hex color to WPF brush."""
return Media.SolidColorBrush(
Media.ColorConverter.ConvertFromString(color_hex)
)
``` | ### `hex_from_brush(solid_brush)` Convert WPF brush to hex color. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
18
19
20
21
22
23
24
25
``` | ```md-code__content
def hex_from_brush(solid_brush):
"""Convert WPF brush to hex color."""
color = solid_brush.Color
color_hex = ''.join(
'{:02X}'.format(int(x)) for x in
[color.A, color.R, color.G, color.B]
)
return '#' + color_hex
``` | ### `get_tabcoloring_theme(usercfg)` Get tab coloring theme from settings. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
99
100
101
102
103
104
105
106
107
108
109
110
111
``` | ```md-code__content
def get_tabcoloring_theme(usercfg):
"""Get tab coloring theme from settings."""
tabcfgs = _get_tabcoloring_cfgs(usercfg)
theme = types.TabColoringTheme()
theme.SortDocTabs = _get_sort_colorize_docs(tabcfgs)
theme.TabStyle = _get_tabstyle(tabcfgs)
theme.FamilyTabStyle = _get_family_tabstyle(tabcfgs)
theme.TabOrderRules = _get_tab_orderrules(tabcfgs)
theme.TabFilterRules = _get_tab_filterrules(tabcfgs)
return theme
``` | ### `reset_tab_ordercolors(usercfg, theme)` Reset tab order colors to internal default. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
114
115
116
117
``` | ```md-code__content
def reset_tab_ordercolors(usercfg, theme):
"""Reset tab order colors to internal default."""
tabcfgs = _get_tabcoloring_cfgs(usercfg)
theme.TabOrderRules = _get_tab_orderrules(tabcfgs, default=True)
``` | ### `set_tabcoloring_theme(usercfg, theme)` Set tab coloring theme in settings. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
120
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def set_tabcoloring_theme(usercfg, theme):
"""Set tab coloring theme in settings."""
tabcfgs = _get_tabcoloring_cfgs(usercfg)
_set_sort_colorize_docs(tabcfgs, theme)
_set_tabstyle(tabcfgs, theme)
_set_family_tabstyle(tabcfgs, theme)
_set_tab_ordercolors(tabcfgs, theme)
_set_tab_filtercolors(tabcfgs, theme)
``` | ### `get_tab_orderrule(theme, index)` Get coloring rule from active theme, at index. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
132
133
134
``` | ```md-code__content
def get_tab_orderrule(theme, index):
"""Get coloring rule from active theme, at index."""
return hex_from_brush(theme.TabOrderRules[index].Brush)
``` | ### `add_tab_orderrule(theme, color)` Add coloring rule to active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
137
138
139
140
141
``` | ```md-code__content
def add_tab_orderrule(theme, color):
"""Add coloring rule to active theme."""
theme.TabOrderRules.Add(
types.TabColoringRule(hex_to_brush(color))
)
``` | ### `remove_tab_orderrule(theme, index)` Remove coloring rule at index, from active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
144
145
146
``` | ```md-code__content
def remove_tab_orderrule(theme, index):
"""Remove coloring rule at index, from active theme."""
theme.TabOrderRules.RemoveAt(index)
``` | ### `update_tab_orderrule(theme, index, color)` Update coloring rule at index, on active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
149
150
151
152
``` | ```md-code__content
def update_tab_orderrule(theme, index, color):
"""Update coloring rule at index, on active theme."""
tor = theme.TabOrderRules[index]
tor.Brush = hex_to_brush(color)
``` | ### `get_tab_filterrule(theme, index)` Get coloring filter rule from active theme, at index. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
155
156
157
158
159
160
161
162
163
``` | ```md-code__content
def get_tab_filterrule(theme, index):
"""Get coloring filter rule from active theme, at index."""
tfr = theme.TabFilterRules[index]
color = tfr.Brush.Color
color_hex = ''.join(
'{:02X}'.format(int(x)) for x in
[color.A, color.R, color.G, color.B]
)
return '#' + color_hex, str(tfr.TitleFilter)
``` | ### `add_tab_filterrule(theme, color, title_filter)` Add coloring filter rule to active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
166
167
168
169
``` | ```md-code__content
def add_tab_filterrule(theme, color, title_filter):
"""Add coloring filter rule to active theme."""
fc = types.TabColoringRule(hex_to_brush(color), title_filter)
theme.TabFilterRules.Add(fc)
``` | ### `remove_tab_filterrule(theme, index)` Remove coloring filter rule at index, from active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
172
173
174
``` | ```md-code__content
def remove_tab_filterrule(theme, index):
"""Remove coloring filter rule at index, from active theme."""
theme.TabFilterRules.RemoveAt(index)
``` | ### `update_tab_filterrule(theme, index, color=None, title_filter=None)` Update coloring filter rule at index, on active theme. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
177
178
179
180
181
182
183
``` | ```md-code__content
def update_tab_filterrule(theme, index, color=None, title_filter=None):
"""Update coloring filter rule at index, on active theme."""
tfr = theme.TabFilterRules[index]
if color:
tfr.Brush = hex_to_brush(color)
if title_filter:
tfr.TitleFilter = Regex(title_filter)
``` | ### `update_tabstyle(theme, tab_style)` Update current tab style. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
186
187
188
189
190
``` | ```md-code__content
def update_tabstyle(theme, tab_style):
"""Update current tab style."""
for ts in types.TabColoringTheme.AvailableStyles:
if ts.Name == tab_style.Name:
theme.TabStyle = ts
``` | ### `update_family_tabstyle(theme, tab_style)` Update current family tab style. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
193
194
195
196
197
``` | ```md-code__content
def update_family_tabstyle(theme, tab_style):
"""Update current family tab style."""
for ts in types.TabColoringTheme.AvailableStyles:
if ts.Name == tab_style.Name:
theme.FamilyTabStyle = ts
``` | ### `get_doc_colorizer_state()` Get state of document colorizer. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
200
201
202
``` | ```md-code__content
def get_doc_colorizer_state():
"""Get state of document colorizer."""
return types.DocumentTabEventUtils.IsUpdatingDocumentTabs
``` | ### `get_styled_slots()` Get list of current styling slots. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
205
206
207
208
209
``` | ```md-code__content
def get_styled_slots():
"""Get list of current styling slots."""
active_theme = types.DocumentTabEventUtils.TabColoringTheme
if active_theme:
return list(active_theme.StyledDocuments)
``` | ### `toggle_doc_colorizer()` Toggle state of document colorizer. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
212
213
214
215
216
217
218
``` | ```md-code__content
def toggle_doc_colorizer():
"""Toggle state of document colorizer."""
if types.DocumentTabEventUtils.IsUpdatingDocumentTabs:
types.DocumentTabEventUtils.StopGroupingDocumentTabs()
else:
types.DocumentTabEventUtils.StartGroupingDocumentTabs(HOST_APP.uiapp)
return types.DocumentTabEventUtils.IsUpdatingDocumentTabs
``` | ### `reset_doc_colorizer()` Reset document colorizer. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
221
222
223
``` | ```md-code__content
def reset_doc_colorizer():
"""Reset document colorizer."""
types.DocumentTabEventUtils.ResetGroupingDocumentTabs()
``` | ### `init_doc_colorizer(usercfg)` Initialize document colorizer from settings. Source code in `pyrevitlib/pyrevit/revit/tabs.py` | | | | --- | --- | | ```
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
``` | ```md-code__content
def init_doc_colorizer(usercfg):
"""Initialize document colorizer from settings."""
uiapp = HOST_APP.uiapp
if HOST_APP.is_newer_than(2018):
current_tabcolorizer = \
envvars.get_pyrevit_env_var(envvars.TABCOLORIZER_ENVVAR)
new_theme = get_tabcoloring_theme(usercfg)
# cancel out the colorizer from previous runtime version
if current_tabcolorizer:
# TODO: adopt the previous slots state
# prev_theme = current_tabcolorizer.TabColoringTheme
# if prev_theme:
# new_theme.InitSlots(prev_theme)
current_tabcolorizer.StopGroupingDocumentTabs()
# start or stop the document colorizer
types.DocumentTabEventUtils.TabColoringTheme = new_theme
if usercfg.colorize_docs:
types.DocumentTabEventUtils.StartGroupingDocumentTabs(uiapp)
else:
types.DocumentTabEventUtils.StopGroupingDocumentTabs()
# set the new colorizer
envvars.set_pyrevit_env_var(
envvars.TABCOLORIZER_ENVVAR,
types.DocumentTabEventUtils
)
``` | Back to top ## pyRevit Resource Links [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/versionmgr/urls/#pyrevit.versionmgr.urls) # urls pyRevit related links. ## Attributes ### `PYREVIT_LICENSE = Common.PyRevitLabsConsts.LicenseUrl``module-attribute` ### `PYREVIT_CREDITS = Common.PyRevitLabsConsts.CreditsUrl``module-attribute` ### `PYREVIT_WIKI = Common.PyRevitLabsConsts.WikiUrl``module-attribute` ### `PYREVIT_TWITTER = 'https://twitter.com/pyrevit'``module-attribute` ### `PYREVIT_BLOG = Common.PyRevitLabsConsts.BlogsUrl``module-attribute` ### `PYREVIT_DOCS = Common.PyRevitLabsConsts.DocsUrl``module-attribute` ### `PYREVIT_GITHUB = Common.PyRevitLabsConsts.OriginalRepoBasePath``module-attribute` ### `PYREVIT_GITHUBBRANCH = Common.PyRevitLabsConsts.OriginalRepoBasePath + '/tree/{branch}'``module-attribute` ### `PYREVIT_GITHUBMASTER_COMMIT = Common.PyRevitLabsConsts.OriginalRepoBasePath + '/commits/master'``module-attribute` ### `PYREVIT_GITHUBBRANCH_COMMIT = Common.PyRevitLabsConsts.OriginalRepoBasePath + '/commits/{branch}'``module-attribute` ### `PYREVIT_GITHUBISSUES = Common.PyRevitLabsConsts.IssuesUrl``module-attribute` ### `PYREVIT_YOUTUBE = Common.PyRevitLabsConsts.YoutubeUrl``module-attribute` ### `PYREVIT_SUPPORT = Common.PyRevitLabsConsts.SupportUrl``module-attribute` ### `PYREVIT_RELEASENOTES = Common.PyRevitLabsConsts.ReleasesUrl``module-attribute` ### `PROFILE_EIN = 'https://ein.sh'``module-attribute` Back to top ## Revit Output Linkmaker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/output/linkmaker/#pyrevit.output.linkmaker) # linkmaker Handle creation of output window helper links. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `PROTOCOL_NAME = 'revit://outputhelpers?'``module-attribute` ### `LINK_SHOW_ICON = 'M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z'``module-attribute` ### `DEFAULT_LINK = '{ids}'``module-attribute` ## Functions ### `make_link(element_ids, contents=None)` Create link for given element ids. This link is a special format link with revit:// scheme that is handled by the output window to select the provided element ids in current project. Scripts should not call this function directly. Creating clickable element links is handled by the output wrapper object through the :func: `linkify` method. Examples: ```md-code__content output = pyrevit.output.get_output() for idx, elid in enumerate(element_ids): print('{}: {}'.format(idx+1, output.linkify(elid))) ``` Source code in `pyrevitlib/pyrevit/output/linkmaker.py` | | | | --- | --- | | ```
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
``` | ````md-code__content
def make_link(element_ids, contents=None):
"""Create link for given element ids.
This link is a special format link with revit:// scheme that is handled
by the output window to select the provided element ids in current project.
Scripts should not call this function directly. Creating clickable element
links is handled by the output wrapper object through the :func:`linkify`
method.
Examples:
```python
output = pyrevit.output.get_output()
for idx, elid in enumerate(element_ids):
print('{}: {}'.format(idx+1, output.linkify(elid)))
```
"""
get_elementid_value = get_elementid_value_func()
try:
try:
strids = [safe_strtype(get_elementid_value(x)) for x in element_ids]
except TypeError:
strids = [safe_strtype(get_elementid_value(element_ids))]
except AttributeError:
raise ValueError("One or more items are not ElementIds")
elementquery = ('element[]={}'.format(strid) for strid in strids)
reviturl = '&'.join(elementquery)
link_title = ', '.join(strids)
if len(reviturl) >= 2000:
alertjs = 'alert("Url was too long and discarded!");'
linkattrs_select = 'href="#" onClick="{}"'.format(alertjs)
linkattrs_show = linkattrs_select
else:
base_link = 'href="{}{}{}&show={{}}"'.format(
PROTOCOL_NAME, '&command=select&', reviturl
)
linkattrs_select = base_link.format("false")
linkattrs_show = base_link.format("true")
return DEFAULT_LINK.format(
attrs_select=linkattrs_select,
attrs_show=linkattrs_show,
ids=contents or link_title,
show_icon=LINK_SHOW_ICON
)
```` | Back to top ## Revit Unit Conversion [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/units/#pyrevit.revit.units) # units Unit conversion utilities for Revit. ## Attributes ## Functions ### `format_area(area_value, doc=None)` Return formatted area value in document units. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `area_value` | `float` | area value | _required_ | | `doc` | `Document` | Revit document, defaults to current | `None` | Returns: | Type | Description | | --- | --- | | `str` | formatted value | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
``` | ```md-code__content
def format_area(area_value, doc=None):
"""Return formatted area value in document units.
Args:
area_value (float): area value
doc (DB.Document, optional): Revit document, defaults to current
Returns:
(str): formatted value
"""
doc = doc or DOCS.doc
if HOST_APP.is_newer_than(2021):
return DB.UnitFormatUtils.Format(units=doc.GetUnits(),
specTypeId=DB.SpecTypeId.Area,
value=area_value,
forEditing=False)
else:
return DB.UnitFormatUtils.Format(units=doc.GetUnits(),
unitType=DB.UnitType.UT_Area,
value=area_value,
maxAccuracy=False,
forEditing=False)
``` | ### `format_slope(slope_value, doc=None)` Return formatted slope value in document units. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `slope_value` | `float` | slope value | _required_ | | `doc` | `Document` | Revit document, defaults to current | `None` | Returns: | Type | Description | | --- | --- | | `str` | formatted value | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
``` | ```md-code__content
def format_slope(slope_value, doc=None):
"""Return formatted slope value in document units.
Args:
slope_value (float): slope value
doc (DB.Document, optional): Revit document, defaults to current
Returns:
(str): formatted value
"""
doc = doc or DOCS.doc
if HOST_APP.is_newer_than(2021):
return DB.UnitFormatUtils.Format(units=doc.GetUnits(),
specTypeId=DB.SpecTypeId.Slope,
value=slope_value,
forEditing=False)
else:
return DB.UnitFormatUtils.Format(units=doc.GetUnits(),
unitType=DB.UnitType.UT_Slope,
value=slope_value,
maxAccuracy=False,
forEditing=False)
``` | ### `project_to_viewport(xyz, view)` Project a point to viewport coordinates. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xyz` | `XYZ` | point to project | _required_ | | `view` | `View` | target view | _required_ | Returns: | Type | Description | | --- | --- | | `UV` | \[description\] | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
68
69
70
71
72
73
74
75
76
77
78
79
80
``` | ```md-code__content
def project_to_viewport(xyz, view):
"""Project a point to viewport coordinates.
Args:
xyz (DB.XYZ): point to project
view (DB.View): target view
Returns:
(DB.UV): [description]
"""
plane = _create_view_plane(view)
uv, _ = plane.Project(xyz)
return uv
``` | ### `project_to_world(uv, view)` Get view-based point (UV) back to model coordinates. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `uv` | `UV` | point on a view | _required_ | | `view` | `View` | view to get coordinates from | _required_ | Returns: | Type | Description | | --- | --- | | `XYZ` | point in world coordinates | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
``` | ```md-code__content
def project_to_world(uv, view):
"""Get view-based point (UV) back to model coordinates.
Args:
uv (DB.UV): point on a view
view (DB.View): view to get coordinates from
Returns:
(DB.XYZ): point in world coordinates
"""
plane = _create_view_plane(view)
trf = DB.Transform.Identity
trf.BasisX = plane.XVec
trf.BasisY = plane.YVec
trf.BasisZ = plane.Normal
trf.Origin = plane.Origin
return trf.OfPoint(DB.XYZ(uv.U, uv.V, 0))
``` | ### `get_spec_name(forge_id)` Returns the measurable spec name for the given unit id. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `forge_id` | `ForgeTypeId` | Unit id | _required_ | Returns: | Type | Description | | --- | --- | | `str` | Spec name | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
102
103
104
105
106
107
108
109
110
111
112
113
114
``` | ```md-code__content
def get_spec_name(forge_id):
"""Returns the measurable spec name for the given unit id.
Args:
forge_id (DB.ForgeTypeId): Unit id
Returns:
(str): Spec name
"""
if HOST_APP.is_newer_than(2021) \
and DB.UnitUtils.IsMeasurableSpec(forge_id):
return DB.UnitUtils.GetTypeCatalogStringForSpec(forge_id)
return ""
``` | ### `get_unit_name(forge_id)` Returns the unit name for the given unit id. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `forge_id` | `ForgeTypeId` | Unit id | _required_ | Returns: | Type | Description | | --- | --- | | `str` | Unit name | Source code in `pyrevitlib/pyrevit/revit/units.py` | | | | --- | --- | | ```
117
118
119
120
121
122
123
124
125
126
127
128
129
``` | ```md-code__content
def get_unit_name(forge_id):
"""Returns the unit name for the given unit id.
Args:
forge_id (DB.ForgeTypeId): Unit id
Returns:
(str): Unit name
"""
if HOST_APP.is_newer_than(2021) \
and DB.UnitUtils.IsUnit(forge_id):
return DB.UnitUtils.GetTypeCatalogStringForUnit(forge_id)
return ""
``` | Back to top ## Revit File Management [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/files/#pyrevit.revit.files) # files Helper functions for working with revit files. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Functions ### `cleanup_backups(main_revitfile)` Remove all incremental saves of the given Revit file. Source code in `pyrevitlib/pyrevit/revit/files.py` | | | | --- | --- | | ```
16
17
18
19
20
21
22
23
24
25
26
27
28
29
``` | ```md-code__content
def cleanup_backups(main_revitfile):
"""Remove all incremental saves of the given Revit file."""
file_dir = op.dirname(main_revitfile)
fname, fext = op.splitext(op.basename(main_revitfile))
backup_fname = re.compile(r'{}\.\d\d\d\d\.{}'.format(fname,
fext.replace('.', '')))
for f in os.listdir(file_dir):
if backup_fname.findall(f):
file_path = op.join(file_dir, f)
try:
os.remove(file_path)
except Exception as osremove_err:
mlogger.error('Error backup file cleanup on: %s | %s',
file_path, osremove_err)
``` | ### `correct_text_encoding(filename)` Convert encoding of text file generated by Revit to UTF-8. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filename` | `str` | file path | _required_ | Source code in `pyrevitlib/pyrevit/revit/files.py` | | | | --- | --- | | ```
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
``` | ```md-code__content
def correct_text_encoding(filename):
"""Convert encoding of text file generated by Revit to UTF-8.
Args:
filename (str): file path
"""
fcontent = None
if coreutils.check_encoding_bom(filename, bom_bytes=codecs.BOM_UTF16):
with codecs.open(filename, 'r', 'utf_16_le') as oldf:
fcontent = oldf.readlines()
elif coreutils.check_encoding_bom(filename, bom_bytes=codecs.BOM_UTF8):
with codecs.open(filename, 'r', 'utf_8') as oldf:
fcontent = oldf.readlines()
with codecs.open(filename, 'w', 'utf-8') as newf:
newf.writelines(fcontent)
``` | ### `read_text(filepath)` Safely read text files with Revit encoding. Source code in `pyrevitlib/pyrevit/revit/files.py` | | | | --- | --- | | ```
50
51
52
53
``` | ```md-code__content
def read_text(filepath):
"""Safely read text files with Revit encoding."""
with codecs.open(filepath, 'r', 'utf_16_le') as text_file:
return text_file.read()
``` | ### `write_text(filepath, contents)` Safely write text files with Revit encoding. Source code in `pyrevitlib/pyrevit/revit/files.py` | | | | --- | --- | | ```
56
57
58
59
60
``` | ```md-code__content
def write_text(filepath, contents):
"""Safely write text files with Revit encoding."""
# if 'utf_16_le' is specified, codecs will not write the BOM
with codecs.open(filepath, 'w', 'utf_16') as text_file:
text_file.write(contents)
``` | ### `get_file_info(filepath)` Returns file information. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `filepath` | `str` | file path | _required_ | Returns: | Type | Description | | --- | --- | | `RevitModelFile` | file information | Source code in `pyrevitlib/pyrevit/revit/files.py` | | | | --- | --- | | ```
63
64
65
66
67
68
69
70
71
72
``` | ```md-code__content
def get_file_info(filepath):
"""Returns file information.
Args:
filepath (str): file path
Returns:
(RevitModelFile): file information
"""
return TargetApps.Revit.RevitModelFile(filepath)
``` | Back to top ## Script Type Preparation [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/typemaker/#pyrevit.runtime.typemaker) # typemaker Prepare and compile script types. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_avail_type(extension, cmd_component, module_builder=None)` Source code in `pyrevitlib/pyrevit/runtime/typemaker.py` | | | | --- | --- | | ```
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
``` | ```md-code__content
def create_avail_type(extension, cmd_component, module_builder=None):
if cmd_component.type_id == exts.LINK_BUTTON_POSTFIX:
mlogger.debug(
'Skipped creating availability type for: %s', cmd_component
)
return
# create command availability class for this command
mlogger.debug('Creating availability type for: %s', cmd_component)
# set the name of the created type
cmd_component.avail_class_name = \
cmd_component.class_name + runtime.CMD_AVAIL_NAME_POSTFIX
if module_builder:
context_str = cmd_component.context.lower()
if context_str == exts.CTX_SELETION:
bundletypemaker.create_selection_avail_type(
module_builder=module_builder,
cmd_component=cmd_component
)
elif context_str == exts.CTX_ZERODOC:
bundletypemaker.create_zerodoc_avail_type(
module_builder=module_builder,
cmd_component=cmd_component
)
else:
bundletypemaker.create_extended_avail_type(
module_builder=module_builder,
cmd_component=cmd_component
)
mlogger.debug(
'Successfully created availability type for: %s', cmd_component)
``` | ### `create_exec_types(extension, cmd_component, module_builder=None)` Source code in `pyrevitlib/pyrevit/runtime/typemaker.py` | | | | --- | --- | | ```
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
``` | ```md-code__content
def create_exec_types(extension, cmd_component, module_builder=None):
mlogger.debug('Command language is: %s', cmd_component.script_language)
# set the name of the created type
cmd_component.class_name = cmd_component.unique_name
if module_builder:
### create the executor types
## first highly custom button types
# if invoke
if cmd_component.type_id == exts.INVOKE_BUTTON_POSTFIX:
invoketypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
# if link
elif cmd_component.type_id == exts.LINK_BUTTON_POSTFIX:
# link buttons don't need types
mlogger.debug('Skipped creating executor type for: %s',
cmd_component)
# if content
elif cmd_component.type_id == exts.CONTENT_BUTTON_POSTFIX:
# link buttons don't need types
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
# if url
elif cmd_component.type_id == exts.URL_BUTTON_POSTFIX:
urltypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
## now language based button types
# if python
elif cmd_component.script_language == exts.PYTHON_LANG:
pythontypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
# if dynamo
elif cmd_component.script_language == exts.DYNAMO_LANG:
dynamotypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
# if anything else
else:
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
``` | ### `make_bundle_types(extension, cmd_component, module_builder=None)` Create the types for the bundle. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | | `cmd_component` | `GenericUICommand` | command | _required_ | | `module_builder` | `ModuleBuilder` | module builder. | `None` | Source code in `pyrevitlib/pyrevit/runtime/typemaker.py` | | | | --- | --- | | ```
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
``` | ```md-code__content
def make_bundle_types(extension, cmd_component, module_builder=None):
"""Create the types for the bundle.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
cmd_component (pyrevit.extensions.genericcomps.GenericUICommand):
command
module_builder (ModuleBuilder): module builder.
"""
# make command interface type for the given command
try:
create_exec_types(extension, cmd_component, module_builder)
except Exception as createtype_err:
mlogger.error('Error creating appropriate exec types for: %s | %s',
cmd_component, createtype_err)
# create availability types if necessary
if cmd_component.context:
try:
create_avail_type(extension, cmd_component, module_builder)
except Exception as createtype_err:
mlogger.error('Error creating appropriate avail types for: %s | %s',
cmd_component, createtype_err)
``` | Back to top ## URL Type Maker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/urltypemaker/#pyrevit.runtime.urltypemaker) # urltypemaker Prepare and compile url script types. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_executor_type(extension, module_builder, cmd_component)` Create the dotnet type for the executor. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | | `module_builder` | `ModuleBuilder` | module builder | _required_ | | `cmd_component` | `GenericUICommand` | command component | _required_ | Source code in `pyrevitlib/pyrevit/runtime/urltypemaker.py` | | | | --- | --- | | ```
11
12
13
14
15
16
17
18
19
20
21
22
23
24
``` | ```md-code__content
def create_executor_type(extension, module_builder, cmd_component):
"""Create the dotnet type for the executor.
Args:
extension (Extension): pyRevit extension
module_builder (ModuleBuilder): module builder
cmd_component (GenericUICommand): command component
"""
cmd_component.arguments = [cmd_component.get_target_url()]
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component
)
``` | Back to top ## MathNet Module [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/mathnet/#pyrevit.coreutils.mathnet) # mathnet MathNet importer module. See https://www.mathdotnet.com for documentation. Examples: ```md-code__content from pyrevit.coreutils.mathnet import MathNet ``` ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `MATHNET_LIB = 'MathNet.Numerics'``module-attribute` ### `mathnet_dll = framework.get_dll_file(MATHNET_LIB)``module-attribute` ## Functions Back to top ## pyRevit Core Logger [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/logger/#pyrevit.coreutils.logger) # logger Core logging module for pyRevit. ## Attributes ### `LOG_REC_FORMAT = '%(levelname)s [%(name)s] %(message)s'``module-attribute` ### `LOG_REC_FORMAT_HEADER = coreutils.prepare_html_str('%(levelname)s [%(name)s] %(message)s')``module-attribute` ### `LOG_REC_FORMAT_HEADER_NO_NAME = coreutils.prepare_html_str('%(levelname)s\n%(message)s')``module-attribute` ### `LOG_REC_FORMAT_EMOJI = '{emoji} %(levelname)s [%(name)s] %(message)s'``module-attribute` ### `LOG_REC_FORMAT_FILE = '%(asctime)s %(levelname)s [%(name)s] %(message)s'``module-attribute` ### `LOG_REC_FORMAT_FILE_C = '%(asctime)s %(levelname)s [<{}> %(name)s] %(message)s'``module-attribute` ### `LOG_REC_FORMAT_HTML = coreutils.prepare_html_str('
{message}
')``module-attribute` ### `LOG_REC_CLASS_ERROR = 'logerror'``module-attribute` ### `LOG_REC_FORMAT_ERROR = LOG_REC_FORMAT_HTML.format(style=LOG_REC_CLASS_ERROR, message=LOG_REC_FORMAT_HEADER)``module-attribute` ### `LOG_REC_CLASS_WARNING = 'logwarning'``module-attribute` ### `LOG_REC_FORMAT_WARNING = LOG_REC_FORMAT_HTML.format(style=LOG_REC_CLASS_WARNING, message=LOG_REC_FORMAT_HEADER)``module-attribute` ### `LOG_REC_CLASS_CRITICAL = 'logcritical'``module-attribute` ### `LOG_REC_FORMAT_CRITICAL = LOG_REC_FORMAT_HTML.format(style=LOG_REC_CLASS_CRITICAL, message=LOG_REC_FORMAT_HEADER)``module-attribute` ### `LOG_REC_CLASS_SUCCESS = 'logsuccess'``module-attribute` ### `LOG_REC_FORMAT_SUCCESS = LOG_REC_FORMAT_HTML.format(style=LOG_REC_CLASS_SUCCESS, message=LOG_REC_FORMAT_HEADER_NO_NAME)``module-attribute` ### `LOG_REC_CLASS_DEPRECATE = 'logdeprecate'``module-attribute` ### `LOG_REC_FORMAT_DEPRECATE = LOG_REC_FORMAT_HTML.format(style=LOG_REC_CLASS_DEPRECATE, message=LOG_REC_FORMAT_HEADER_NO_NAME)``module-attribute` ### `DEFAULT_LOGGING_LEVEL = logging.WARNING``module-attribute` ### `DEPRECATE_LOG_LEVEL = 25``module-attribute` ### `SUCCESS_LOG_LEVEL = 80``module-attribute` ### `FILE_LOG_FILENAME = '{}runtime.log'.format(PYREVIT_FILE_PREFIX_STAMPED)``module-attribute` ### `FILE_LOG_FILEPATH = op.join(PYREVIT_VERSION_APP_DIR, FILE_LOG_FILENAME)``module-attribute` ### `FILE_LOGGING_DEFAULT_STATE = False``module-attribute` ### `stdout_hndlr = logging.StreamHandler(sys.stdout)``module-attribute` ### `default_formatter = logging.Formatter(LOG_REC_FORMAT)``module-attribute` ### `formatters = {SUCCESS_LOG_LEVEL: logging.Formatter(LOG_REC_FORMAT_SUCCESS), logging.ERROR: logging.Formatter(LOG_REC_FORMAT_ERROR), logging.WARNING: logging.Formatter(LOG_REC_FORMAT_WARNING), logging.CRITICAL: logging.Formatter(LOG_REC_FORMAT_CRITICAL), DEPRECATE_LOG_LEVEL: logging.Formatter(LOG_REC_FORMAT_DEPRECATE)}``module-attribute` ### `file_hndlr = logging.FileHandler(FILE_LOG_FILEPATH, mode='a', delay=True)``module-attribute` ### `file_formatter = logging.Formatter(LOG_REC_FORMAT_FILE)``module-attribute` ### `loggers = {}``module-attribute` ## Classes ### `DispatchingFormatter(log_formatters, log_default_formatter)` Bases: `object` Dispatching formatter to format by log level. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `log_formatters` | `dict[int` | logging.Formatter\]):
dict of level:formatter key pairs | _required_ | | `log_default_formatter` | `Formatter` | default formatter | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
92
93
94
``` | ```md-code__content
def __init__(self, log_formatters, log_default_formatter):
self._formatters = log_formatters
self._default_formatter = log_default_formatter
``` | #### Functions ##### `format(record)` Format given record by log level. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
96
97
98
99
100
``` | ```md-code__content
def format(self, record):
"""Format given record by log level."""
formatter = self._formatters.get(record.levelno,
self._default_formatter)
return formatter.format(record)
``` | ### `LoggerWrapper(*args)` Bases: `Logger` Custom logging object. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
105
106
107
108
109
``` | ```md-code__content
def __init__(self, *args):
logging.Logger.__init__(self, *args)
self._has_errors = False
self._filelogstate = False
self._curlevel = DEFAULT_LOGGING_LEVEL
``` | #### Functions ##### `callHandlers(record)` Override logging.Logger.callHandlers. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
126
127
128
129
130
131
132
133
134
135
136
``` | ```md-code__content
def callHandlers(self, record):
"""Override logging.Logger.callHandlers."""
for hdlr in self.handlers:
# stream-handler only records based on current level
if isinstance(hdlr, logging.StreamHandler) \
and record.levelno >= self._curlevel:
hdlr.handle(record)
# file-handler must record everything
elif isinstance(hdlr, logging.FileHandler) \
and self._filelogstate:
hdlr.handle(record)
``` | ##### `isEnabledFor(level)` Override logging.Logger.isEnabledFor. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
``` | ```md-code__content
def isEnabledFor(self, level):
"""Override logging.Logger.isEnabledFor."""
# update current logging level and file logging state
self._filelogstate = \
envvars.get_pyrevit_env_var(envvars.FILELOGGING_ENVVAR)
self._curlevel = \
envvars.get_pyrevit_env_var(envvars.LOGGING_LEVEL_ENVVAR)
# the loader assembly sets EXEC_PARAMS.debug_mode to true if
# user Ctrl-clicks on the button at script runtime.
if EXEC_PARAMS.debug_mode:
self._curlevel = logging.DEBUG
# if file logging is disabled, return the current logging level
# but if it's enabled, return the file logging level so the record
# is generated and logged by file-handler. The stream-handler still
# outputs the record based on the current logging level
if self._filelogstate:
return level >= logging.DEBUG
return level >= self._curlevel
``` | ##### `is_enabled_for(level)` Check if logger is enabled for level in pyRevit environment. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
160
161
162
163
164
165
166
167
168
169
170
``` | ```md-code__content
def is_enabled_for(self, level):
"""Check if logger is enabled for level in pyRevit environment."""
self._curlevel = \
envvars.get_pyrevit_env_var(envvars.LOGGING_LEVEL_ENVVAR)
# the loader assembly sets EXEC_PARAMS.debug_mode to true if
# user Ctrl-clicks on the button at script runtime.
if EXEC_PARAMS.debug_mode:
self._curlevel = logging.DEBUG
return level >= self._curlevel
``` | ##### `has_errors()` Check if logger has reported any errors. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
176
177
178
``` | ```md-code__content
def has_errors(self):
"""Check if logger has reported any errors."""
return self._has_errors
``` | ##### `set_level(level)` Set logging level to level. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
180
181
182
``` | ```md-code__content
def set_level(self, level):
"""Set logging level to level."""
self._reset_logger_env_vars(level)
``` | ##### `set_quiet_mode()` Activate quiet mode. All log levels are disabled. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
184
185
186
``` | ```md-code__content
def set_quiet_mode(self):
"""Activate quiet mode. All log levels are disabled."""
self._reset_logger_env_vars(logging.CRITICAL)
``` | ##### `set_verbose_mode()` Activate verbose mode. Log levels >= INFO are enabled. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
188
189
190
``` | ```md-code__content
def set_verbose_mode(self):
"""Activate verbose mode. Log levels >= INFO are enabled."""
self._reset_logger_env_vars(logging.INFO)
``` | ##### `set_debug_mode()` Activate debug mode. Log levels >= DEBUG are enabled. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
192
193
194
``` | ```md-code__content
def set_debug_mode(self):
"""Activate debug mode. Log levels >= DEBUG are enabled."""
self._reset_logger_env_vars(logging.DEBUG)
``` | ##### `reset_level()` Reset logging level back to default. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
196
197
198
``` | ```md-code__content
def reset_level(self):
"""Reset logging level back to default."""
self._reset_logger_env_vars(DEFAULT_LOGGING_LEVEL)
``` | ##### `get_level()` Return current logging level. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
200
201
202
``` | ```md-code__content
def get_level(self):
"""Return current logging level."""
return envvars.get_pyrevit_env_var(envvars.LOGGING_LEVEL_ENVVAR)
``` | ##### `log_parse_except(parsed_file, parse_ex)` Logs a file parsing exception. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `parsed_file` | `str` | File path that failed the parsing | _required_ | | `parse_ex` | `Exception` | Parsing exception | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
``` | ```md-code__content
def log_parse_except(self, parsed_file, parse_ex):
"""Logs a file parsing exception.
Args:
parsed_file (str): File path that failed the parsing
parse_ex (Exception): Parsing exception
"""
err_msg = 'Error while parsing file:\n{file}\n' \
'Error type: {type}\n' \
'Error Message: {errmsg}\n' \
'Line/Column: {lineno}/{colno}\n' \
'Line Text: {linetext}' \
.format(file=parsed_file,
type=parse_ex.__class__.__name__,
errmsg=parse_ex.msg if hasattr(parse_ex, 'msg') else "",
lineno=parse_ex.lineno if hasattr(parse_ex, 'lineno') else 0,
colno=parse_ex.offset if hasattr(parse_ex, 'offset') else 0,
linetext=parse_ex.text if hasattr(parse_ex, 'text') else "",
)
self.error(coreutils.prepare_html_str(err_msg))
``` | ##### `success(message, *args, **kws)` Log a success message. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | success message | _required_ | | `*args` | `Any` | extra agruments passed to the log function | `()` | | `**kws` | `Any` | extra agruments passed to the log function | `{}` | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
225
226
227
228
229
230
231
232
233
234
235
``` | ```md-code__content
def success(self, message, *args, **kws):
"""Log a success message.
Args:
message (str): success message
*args (Any): extra agruments passed to the log function
**kws (Any): extra agruments passed to the log function
"""
if self.isEnabledFor(SUCCESS_LOG_LEVEL):
# Yes, logger takes its '*args' as 'args'.
self._log(SUCCESS_LOG_LEVEL, message, args, **kws)
``` | ##### `deprecate(message, *args, **kws)` Log a deprecation message. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | deprecation message | _required_ | | `*args` | `Any` | extra agruments passed to the log function | `()` | | `**kws` | `Any` | extra agruments passed to the log function | `{}` | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
237
238
239
240
241
242
243
244
245
246
247
``` | ```md-code__content
def deprecate(self, message, *args, **kws):
"""Log a deprecation message.
Args:
message (str): deprecation message
*args (Any): extra agruments passed to the log function
**kws (Any): extra agruments passed to the log function
"""
if self.isEnabledFor(DEPRECATE_LOG_LEVEL):
# Yes, logger takes its '*args' as 'args'.
self._log(DEPRECATE_LOG_LEVEL, message, args, **kws)
``` | ##### `dev_log(source, message='')` Appends a message to a log file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source` | `str` | source of the message | _required_ | | `message` | `str` | message to log | `''` | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
``` | ```md-code__content
def dev_log(self, source, message=''):
"""Appends a message to a log file.
Args:
source (str): source of the message
message (str): message to log
"""
devlog_fname = \
'{}.log'.format(EXEC_PARAMS.command_uniqueid or self.name)
with open(op.join(USER_DESKTOP, devlog_fname), 'a') as devlog_file:
devlog_file.writelines('{tstamp} [{exid}] {src}: {msg}\n'.format(
tstamp=EXEC_PARAMS.exec_timestamp,
exid=EXEC_PARAMS.exec_id,
src=source,
msg=message,
))
``` | ## Functions ### `get_stdout_hndlr()` Return stdout logging handler object. Returns: | Type | Description | | --- | --- | | `StreamHandler` | configured instance of python's native stream handler | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def get_stdout_hndlr():
"""Return stdout logging handler object.
Returns:
(logging.StreamHandler):
configured instance of python's native stream handler
"""
global stdout_hndlr #pylint: disable=W0603
return stdout_hndlr
``` | ### `get_file_hndlr()` Return file logging handler object. Returns: | Type | Description | | --- | --- | | `FileHandler` | configured instance of python's native stream handler | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
``` | ```md-code__content
def get_file_hndlr():
"""Return file logging handler object.
Returns:
(logging.FileHandler):
configured instance of python's native stream handler
"""
global file_hndlr #pylint: disable=W0603
if EXEC_PARAMS.command_mode:
cmd_file_hndlr = logging.FileHandler(FILE_LOG_FILEPATH,
mode='a', delay=True)
logformat = LOG_REC_FORMAT_FILE_C.format(EXEC_PARAMS.command_name)
formatter = logging.Formatter(logformat)
cmd_file_hndlr.setFormatter(formatter)
return cmd_file_hndlr
else:
return file_hndlr
``` | ### `get_logger(logger_name)` Register and return a logger with given name. Caches all registered loggers and returns the same logger object on second call with the same logger name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `logger_name` | `str` | logger name | _required_ | Returns: | Type | Description | | --- | --- | | `LoggerWrapper` | logger object wrapper python's native logger | Examples: ```md-code__content get_logger('my command') ``` Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
``` | ````md-code__content
def get_logger(logger_name):
"""Register and return a logger with given name.
Caches all registered loggers and returns the same logger object on
second call with the same logger name.
Args:
logger_name (str): logger name
Returns:
(LoggerWrapper): logger object wrapper python's native logger
Examples:
```python
get_logger('my command')
```

"""
if loggers.get(logger_name):
return loggers.get(logger_name)
else:
logger = logging.getLogger(logger_name) # type: LoggerWrapper
logger.addHandler(get_stdout_hndlr())
logger.propagate = False
logger.addHandler(get_file_hndlr())
loggers.update({logger_name: logger})
return logger
```` | ### `set_file_logging(status)` Set file logging status (enable/disable). Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `status` | `bool` | True to enable, False to disable | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
355
356
357
358
359
360
361
``` | ```md-code__content
def set_file_logging(status):
"""Set file logging status (enable/disable).
Args:
status (bool): True to enable, False to disable
"""
envvars.set_pyrevit_env_var(envvars.FILELOGGING_ENVVAR, status)
``` | ### `loggers_have_errors()` Check if any errors have been reported by any of registered loggers. Source code in `pyrevitlib/pyrevit/coreutils/logger.py` | | | | --- | --- | | ```
364
365
366
367
368
369
``` | ```md-code__content
def loggers_have_errors():
"""Check if any errors have been reported by any of registered loggers."""
for logger in loggers.values():
if logger.has_errors():
return True
return False
``` | Back to top ## Excel File Interop [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/xl/#pyrevit.interop.xl) # xl Read and Write Excel Files. ## Functions ### `load(xlfile, sheets=[], columns=[], datatype=None, headers=True)` Read data from Excel file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xlfile` | `str` | full path of the excel file to read | _required_ | | `sheets` | `list` | worksheets to read. Defaults to all the sheets. | `[]` | | `columns` | `list` | Names to give to the columns.
It builds a dictionary for each row with the column name and value.
If none given (default), it returns a simple list of values. | `[]` | | `datatype` | `type` | Type of the data. Defaults to None. | `None` | | `headers` | `bool` | Whether to use the first row as headers.
Defaults to True. | `True` | Returns: | Type | Description | | --- | --- | | `dict[str, dict[str, Any]]` | Excel data grouped by worksheet.
Each worksheet is a dictionary with `headers` and `rows`. | Source code in `pyrevitlib/pyrevit/interop/xl.py` | | | | --- | --- | | ```
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
``` | ```md-code__content
def load(xlfile, sheets=[], columns=[], datatype=None, headers=True):
"""Read data from Excel file.
Args:
xlfile (str): full path of the excel file to read
sheets (list, optional): worksheets to read. Defaults to all the sheets.
columns (list, optional): Names to give to the columns.
It builds a dictionary for each row with the column name and value.
If none given (default), it returns a simple list of values.
datatype (type, optional): Type of the data. Defaults to None.
headers (bool, optional): Whether to use the first row as headers.
Defaults to True.
Returns:
(dict[str, dict[str, Any]]): Excel data grouped by worksheet.
Each worksheet is a dictionary with `headers` and `rows`.
"""
xldata = {}
xlwb = xlrd.open_workbook(xlfile)
for xlsheet in xlwb.sheets():
if sheets:
if xlsheet.name in sheets:
xldata[xlsheet.name] = _read_xlsheet(xlsheet,
columns=columns,
datatype=datatype,
headers=headers)
else:
xldata[xlsheet.name] = _read_xlsheet(xlsheet,
columns=columns,
datatype=datatype,
headers=headers)
return xldata
``` | ### `dump(xlfile, datadict)` Write data to Excel file. Creates a worksheet for each item of the input dictionary. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xlfile` | `str` | full path of the target excel file | _required_ | | `datadict` | `dict[str, list]` | dictionary of worksheets names and data | _required_ | Source code in `pyrevitlib/pyrevit/interop/xl.py` | | | | --- | --- | | ```
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
``` | ```md-code__content
def dump(xlfile, datadict):
"""Write data to Excel file.
Creates a worksheet for each item of the input dictionary.
Args:
xlfile (str): full path of the target excel file
datadict (dict[str, list]): dictionary of worksheets names and data
"""
xlwb = xlsxwriter.Workbook(xlfile)
# bold = xlwb.add_format({'bold': True})
for xlsheetname, xlsheetdata in datadict.items():
xlsheet = xlwb.add_worksheet(xlsheetname)
for idx, data in enumerate(xlsheetdata):
xlsheet.write_row(idx, 0, data)
xlwb.close()
``` | Back to top ## Revit Element Selection Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/selection/#pyrevit.revit.selection) # selection Elements selection utilities. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Classes ### `ElementSelection(element_list=None)` Element selection handler. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_list` | `list[Element]` | list of selected elements | `None` | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
32
33
34
35
36
37
38
39
40
``` | ```md-code__content
def __init__(self, element_list=None):
if element_list is None:
if HOST_APP.uidoc:
self._refs = \
[x for x in HOST_APP.uidoc.Selection.GetElementIds()]
else:
self._refs = []
else:
self._refs = ElementSelection.get_element_ids(element_list)
``` | #### Attributes ##### `is_empty``property` ##### `elements``property` ##### `element_ids``property` ##### `first``property` ##### `last``property` #### Functions ##### `get_element_ids(mixed_list)``classmethod` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
61
62
63
``` | ```md-code__content
@classmethod
def get_element_ids(cls, mixed_list):
return ensure.ensure_element_ids(mixed_list)
``` | ##### `set_to(element_list)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
87
88
89
90
91
92
``` | ```md-code__content
def set_to(self, element_list):
self._refs = ElementSelection.get_element_ids(element_list)
HOST_APP.uidoc.Selection.SetElementIds(
framework.List[DB.ElementId](self._refs)
)
HOST_APP.uidoc.RefreshActiveView()
``` | ##### `clear()` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
94
95
96
97
98
``` | ```md-code__content
def clear(self):
HOST_APP.uidoc.Selection.SetElementIds(
framework.List[DB.ElementId]([DB.ElementId.InvalidElementId])
)
HOST_APP.uidoc.RefreshActiveView()
``` | ##### `append(element_list)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
100
101
102
``` | ```md-code__content
def append(self, element_list):
self._refs.extend(ElementSelection.get_element_ids(element_list))
self.set_to(self._refs)
``` | ##### `include(element_type)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
104
105
106
107
108
``` | ```md-code__content
def include(self, element_type):
refs = [x for x in self._refs
if isinstance(DOCS.doc.GetElement(x),
element_type)]
return ElementSelection(refs)
``` | ##### `exclude(element_type)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
110
111
112
113
114
``` | ```md-code__content
def exclude(self, element_type):
refs = [x for x in self._refs
if not isinstance(DOCS.doc.GetElement(x),
element_type)]
return ElementSelection(refs)
``` | ##### `no_views()` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
116
117
``` | ```md-code__content
def no_views(self):
return self.exclude(DB.View)
``` | ##### `only_views()` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
119
120
``` | ```md-code__content
def only_views(self):
return self.include(DB.View)
``` | ##### `expand_groups()` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
122
123
124
125
126
127
128
129
``` | ```md-code__content
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
``` | ### `PickByCategorySelectionFilter(category_id)` Bases: `ISelectionFilter` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
133
134
``` | ```md-code__content
def __init__(self, category_id):
self.category_id = category_id
``` | #### Attributes ##### `category_id = category_id``instance-attribute` #### Functions ##### `AllowElement(element)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
137
138
139
140
141
``` | ```md-code__content
def AllowElement(self, element):
if element.Category and self.category_id == element.Category.Id:
return True
else:
return False
``` | ##### `AllowReference(refer, point)` Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
144
145
``` | ```md-code__content
def AllowReference(self, refer, point): # pylint: disable=W0613
return False
``` | ## Functions ### `pick_element(message='')` Asks the user to pick an element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | An optional message to display. | `''` | Returns: | Type | Description | | --- | --- | | `Element` | element selected by the user. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
198
199
200
201
202
203
204
205
206
207
208
``` | ```md-code__content
def pick_element(message=''):
"""Asks the user to pick an element.
Args:
message (str): An optional message to display.
Returns:
(Element): element selected by the user.
"""
return _pick_obj(UI.Selection.ObjectType.Element,
message)
``` | ### `pick_element_by_category(cat_name_or_builtin, message='')` Returns the element of the specified category picked by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | name or built-in category of the element
to pick. | _required_ | | `message` | `str` | message to display on selection.
Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Element` | picked element. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If no category matches the specified name or builtin. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
``` | ```md-code__content
def pick_element_by_category(cat_name_or_builtin, message=''):
"""Returns the element of the specified category picked by the user.
Args:
cat_name_or_builtin (str): name or built-in category of the element
to pick.
message (str, optional): message to display on selection.
Defaults to ''.
Returns:
(Element): picked element.
Raises:
PyRevitException: If no category matches the specified name or builtin.
"""
category = query.get_category(cat_name_or_builtin)
if category:
pick_filter = PickByCategorySelectionFilter(category.Id)
return _pick_obj(UI.Selection.ObjectType.Element,
message,
selection_filter=pick_filter)
else:
raise PyRevitException("Can not determine category id from: {}"
.format(cat_name_or_builtin))
``` | ### `pick_elementpoint(message='', world=False)` Returns the element point selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | | `world` | `bool` | whether to use world coordinates. Defaults to False. | `False` | Returns: | Type | Description | | --- | --- | | `PointOnElement` | The selected point. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
237
238
239
240
241
242
243
244
245
246
247
248
249
``` | ```md-code__content
def pick_elementpoint(message='', world=False):
"""Returns the element point selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
world (bool, optional): whether to use world coordinates. Defaults to False.
Returns:
(PointOnElement): The selected point.
"""
return _pick_obj(UI.Selection.ObjectType.PointOnElement,
message,
world=world)
``` | ### `pick_edge(message='')` Returns the edge selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Edge` | The selected edge. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
252
253
254
255
256
257
258
259
260
261
262
``` | ```md-code__content
def pick_edge(message=''):
"""Returns the edge selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(Edge): The selected edge.
"""
return _pick_obj(UI.Selection.ObjectType.Edge,
message)
``` | ### `pick_face(message='')` Returns the face selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `Face` | The selected face. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
265
266
267
268
269
270
271
272
273
274
275
``` | ```md-code__content
def pick_face(message=''):
"""Returns the face selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(Face): The selected face.
"""
return _pick_obj(UI.Selection.ObjectType.Face,
message)
``` | ### `pick_linked(message='')` Returns the linked element selected by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | message to display. Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `LinkedElement` | The selected linked element. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
278
279
280
281
282
283
284
285
286
287
288
``` | ```md-code__content
def pick_linked(message=''):
"""Returns the linked element selected by the user.
Args:
message (str, optional): message to display. Defaults to ''.
Returns:
(LinkedElement): The selected linked element.
"""
return _pick_obj(UI.Selection.ObjectType.LinkedElement,
message)
``` | ### `pick_elements(message='')` Asks the user to pick multiple elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | An optional message to display. | `''` | Returns: | Type | Description | | --- | --- | | `list[Element]` | elements selected by the user. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
291
292
293
294
295
296
297
298
299
300
301
302
``` | ```md-code__content
def pick_elements(message=''):
"""Asks the user to pick multiple elements.
Args:
message (str): An optional message to display.
Returns:
(list[Element]): elements selected by the user.
"""
return _pick_obj(UI.Selection.ObjectType.Element,
message,
multiple=True)
``` | ### `pick_elements_by_category(cat_name_or_builtin, message='')` Returns the elements of the specified category picked by the user. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | name or built-in category of the elements
to pick. | _required_ | | `message` | `str` | message to display on selection.
Defaults to ''. | `''` | Returns: | Type | Description | | --- | --- | | `list[Element]` | picked elements. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If no category matches the specified name or builtin. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
``` | ```md-code__content
def pick_elements_by_category(cat_name_or_builtin, message=''):
"""Returns the elements of the specified category picked by the user.
Args:
cat_name_or_builtin (str): name or built-in category of the elements
to pick.
message (str, optional): message to display on selection.
Defaults to ''.
Returns:
(list[Element]): picked elements.
Raises:
PyRevitException: If no category matches the specified name or builtin.
"""
category = query.get_category(cat_name_or_builtin)
if category:
pick_filter = PickByCategorySelectionFilter(category.Id)
return _pick_obj(UI.Selection.ObjectType.Element,
message,
multiple=True,
selection_filter=pick_filter)
else:
raise PyRevitException("Can not determine category id from: {}"
.format(cat_name_or_builtin))
``` | ### `get_picked_elements(message='')` Allows the user to pick multple elements, one at a time. It keeps asking the user to pick an element until no elements are selected. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display. Defaults to ''. | `''` | Yields: | Type | Description | | --- | --- | | `Element` | selected element | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
``` | ```md-code__content
def get_picked_elements(message=''):
"""Allows the user to pick multple elements, one at a time.
It keeps asking the user to pick an element until no elements are selected.
Args:
message (str, optional): The message to display. Defaults to ''.
Yields:
(DB.Element): selected element
"""
picked_element = True
while picked_element:
picked_element = pick_element(message=message)
if not picked_element:
break
yield picked_element
``` | ### `get_picked_elements_by_category(cat_name_or_builtin, message='')` Pick elements by category. Keeps asking the user to pick an element until no elements are selected. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str` | category name or built-in category. | _required_ | | `message` | `str` | message to display while picking elements. | `''` | Yields: | Type | Description | | --- | --- | | `Element` | The picked elements from the specified category. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
``` | ```md-code__content
def get_picked_elements_by_category(cat_name_or_builtin, message=''):
"""Pick elements by category.
Keeps asking the user to pick an element until no elements are selected.
Args:
cat_name_or_builtin (str): category name or built-in category.
message (str, optional): message to display while picking elements.
Yields:
(DB.Element): The picked elements from the specified category.
"""
picked_element = True
while picked_element:
picked_element = pick_element_by_category(cat_name_or_builtin,
message=message)
if not picked_element:
break
yield picked_element
``` | ### `pick_elementpoints(message='', world=False)` Selects element points. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting element points. | `''` | | `world` | `bool` | Select points in world coordinates. Defaults to False. | `False` | Returns: | Type | Description | | --- | --- | | `list[PointOnElement]` | selected element points. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
372
373
374
375
376
377
378
379
380
381
382
383
384
``` | ```md-code__content
def pick_elementpoints(message='', world=False):
"""Selects element points.
Args:
message (str): The message to display when selecting element points.
world (bool, optional): Select points in world coordinates. Defaults to False.
Returns:
(list[PointOnElement]): selected element points.
"""
return _pick_obj(UI.Selection.ObjectType.PointOnElement,
message,
multiple=True, world=world)
``` | ### `pick_edges(message='')` Selects edges. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting edges. | `''` | Returns: | Type | Description | | --- | --- | | `list[Edge]` | selected edges. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
387
388
389
390
391
392
393
394
395
396
397
398
``` | ```md-code__content
def pick_edges(message=''):
"""Selects edges.
Args:
message (str): The message to display when selecting edges.
Returns:
(list[Edge]): selected edges.
"""
return _pick_obj(UI.Selection.ObjectType.Edge,
message,
multiple=True)
``` | ### `pick_faces(message='')` Selects faces. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting the faces. | `''` | Returns: | Type | Description | | --- | --- | | `list[Face]` | selected faces. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
401
402
403
404
405
406
407
408
409
410
411
412
``` | ```md-code__content
def pick_faces(message=''):
"""Selects faces.
Args:
message (str): The message to display when selecting the faces.
Returns:
(list[Face]): selected faces.
"""
return _pick_obj(UI.Selection.ObjectType.Face,
message,
multiple=True)
``` | ### `pick_linkeds(message='')` Selects linked elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | The message to display when selecting linked elements. | `''` | Returns: | Type | Description | | --- | --- | | `list[LinkedElement]` | selected linked elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
415
416
417
418
419
420
421
422
423
424
425
426
``` | ```md-code__content
def pick_linkeds(message=''):
"""Selects linked elements.
Args:
message (str): The message to display when selecting linked elements.
Returns:
(list[LinkedElement]): selected linked elements.
"""
return _pick_obj(UI.Selection.ObjectType.LinkedElement,
message,
multiple=True)
``` | ### `pick_point(message='')` Pick a point from the user interface. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | A message to display when prompting for the point. | `''` | Returns: | Type | Description | | --- | --- | | `tuple or None` | A tuple representing the picked point as (x, y, z)
coordinates, or None if no point was picked or an error occurred. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
429
430
431
432
433
434
435
436
437
438
439
440
441
442
``` | ```md-code__content
def pick_point(message=''):
"""Pick a point from the user interface.
Args:
message (str): A message to display when prompting for the point.
Returns:
(tuple or None): A tuple representing the picked point as (x, y, z)
coordinates, or None if no point was picked or an error occurred.
"""
try:
return HOST_APP.uidoc.Selection.PickPoint(message)
except Exception:
return None
``` | ### `pick_rectangle(message='', pick_filter=None)` Picks elements from the user interface by specifying a rectangular area. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `message` | `str` | A custom message to display when prompting
the user to pick elements. Default is an empty string. | `''` | | `pick_filter` | `object` | An object specifying the filter to apply
when picking elements. Default is None. | `None` | Returns: | Type | Description | | --- | --- | | `list[ElementId]` | The selected elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
``` | ```md-code__content
def pick_rectangle(message='', pick_filter=None):
"""Picks elements from the user interface by specifying a rectangular area.
Args:
message (str, optional): A custom message to display when prompting
the user to pick elements. Default is an empty string.
pick_filter (object, optional): An object specifying the filter to apply
when picking elements. Default is None.
Returns:
(list[DB.ElementId]): The selected elements.
"""
if pick_filter:
return HOST_APP.uidoc.Selection.PickElementsByRectangle(pick_filter,
message)
else:
return HOST_APP.uidoc.Selection.PickElementsByRectangle(message)
``` | ### `get_selection_category_set()` Returns a CategorySet with the categories of the selected elements. Returns: | Type | Description | | --- | --- | | `CategorySet` | categories of the selected elements. | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
464
465
466
467
468
469
470
471
472
473
474
``` | ```md-code__content
def get_selection_category_set():
"""Returns a CategorySet with the categories of the selected elements.
Returns:
(CategorySet): categories of the selected elements.
"""
selection = ElementSelection()
cset = DB.CategorySet()
for element in selection:
cset.Insert(element.Category)
return cset
``` | ### `get_selection()` Returns the current selected items. Returns: | Type | Description | | --- | --- | | `ElementSelection` | the current selected items | Source code in `pyrevitlib/pyrevit/revit/selection.py` | | | | --- | --- | | ```
477
478
479
480
481
482
483
``` | ```md-code__content
def get_selection():
"""Returns the current selected items.
Returns:
(ElementSelection): the current selected items
"""
return ElementSelection()
``` | Back to top ## pyRevit Config Parser [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/configparser/#pyrevit.coreutils.configparser) # configparser Base module for pyRevit config parsing. ## Attributes ### `KEY_VALUE_TRUE = 'True'``module-attribute` ### `KEY_VALUE_FALSE = 'False'``module-attribute` ## Classes ### `PyRevitConfigSectionParser(config_parser, section_name)` Bases: `object` Config section parser object. Handle section options. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
16
17
18
``` | ```md-code__content
def __init__(self, config_parser, section_name):
self._parser = config_parser
self._section_name = section_name
``` | #### Attributes ##### `header``property` Section header. ##### `subheader``property` Section sub-header e.g. Section.SubSection. #### Functions ##### `has_option(option_name)` Check if section contains given option. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
93
94
95
``` | ```md-code__content
def has_option(self, option_name):
"""Check if section contains given option."""
return self._parser.has_option(self._section_name, option_name)
``` | ##### `get_option(op_name, default_value=None)` Get option value or return default. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
97
98
99
100
101
102
103
104
105
``` | ```md-code__content
def get_option(self, op_name, default_value=None):
"""Get option value or return default."""
try:
return self.__getattr__(op_name)
except Exception as opt_get_err:
if default_value is not None:
return default_value
else:
raise opt_get_err
``` | ##### `set_option(op_name, value)` Set value of given option. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
107
108
109
``` | ```md-code__content
def set_option(self, op_name, value):
"""Set value of given option."""
self.__setattr__(op_name, value)
``` | ##### `remove_option(option_name)` Remove given option from section. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
111
112
113
``` | ```md-code__content
def remove_option(self, option_name):
"""Remove given option from section."""
return self._parser.remove_option(self._section_name, option_name)
``` | ##### `has_subsection(section_name)` Check if section has any subsections. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
115
116
117
``` | ```md-code__content
def has_subsection(self, section_name):
"""Check if section has any subsections."""
return True if self.get_subsection(section_name) else False
``` | ##### `add_subsection(section_name)` Add subsection to section. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
119
120
121
122
123
``` | ```md-code__content
def add_subsection(self, section_name):
"""Add subsection to section."""
return self._parser.add_section(
coreutils.make_canonical_name(self._section_name, section_name)
)
``` | ##### `get_subsections()` Get all subsections. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
125
126
127
128
129
130
131
132
``` | ```md-code__content
def get_subsections(self):
"""Get all subsections."""
subsections = []
for section_name in self._parser.sections():
if section_name.startswith(self._section_name + '.'):
subsec = PyRevitConfigSectionParser(self._parser, section_name)
subsections.append(subsec)
return subsections
``` | ##### `get_subsection(section_name)` Get subsection with given name. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
134
135
136
137
138
``` | ```md-code__content
def get_subsection(self, section_name):
"""Get subsection with given name."""
for subsection in self.get_subsections():
if subsection.subheader == section_name:
return subsection
``` | ### `PyRevitConfigParser(cfg_file_path=None)` Bases: `object` Config parser object. Handle config sections and io. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
143
144
145
146
147
148
149
150
151
152
153
154
155
156
``` | ```md-code__content
def __init__(self, cfg_file_path=None):
self._cfg_file_path = cfg_file_path
self._parser = configparser.ConfigParser()
if self._cfg_file_path:
try:
with codecs.open(self._cfg_file_path, 'r', 'utf-8') as cfg_file:
try:
self._parser.readfp(cfg_file)
except AttributeError:
self._parser.read_file(cfg_file)
except (OSError, IOError):
raise PyRevitIOError()
except Exception as read_err:
raise PyRevitException(read_err)
``` | #### Functions ##### `get_config_file_hash()` Get calculated unique hash for this config. Returns: | Type | Description | | --- | --- | | `str` | hash of the config. | Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
170
171
172
173
174
175
176
177
178
179
``` | ```md-code__content
def get_config_file_hash(self):
"""Get calculated unique hash for this config.
Returns:
(str): hash of the config.
"""
with codecs.open(self._cfg_file_path, 'r', 'utf-8') as cfg_file:
cfg_hash = coreutils.get_str_hash(cfg_file.read())
return cfg_hash
``` | ##### `has_section(section_name)` Check if config contains given section. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
181
182
183
184
185
186
187
``` | ```md-code__content
def has_section(self, section_name):
"""Check if config contains given section."""
try:
self.get_section(section_name)
return True
except Exception:
return False
``` | ##### `add_section(section_name)` Add section with given name to config. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
189
190
191
192
``` | ```md-code__content
def add_section(self, section_name):
"""Add section with given name to config."""
self._parser.add_section(section_name)
return PyRevitConfigSectionParser(self._parser, section_name)
``` | ##### `get_section(section_name)` Get section with given name. Raises: | Type | Description | | --- | --- | | `AttributeError` | if section is missing | Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
``` | ```md-code__content
def get_section(self, section_name):
"""Get section with given name.
Raises:
AttributeError: if section is missing
"""
# check is section with full name is available
if self._parser.has_section(section_name):
return PyRevitConfigSectionParser(self._parser, section_name)
# if not try to match with section_name.subsection
# if there is a section_name.subsection defined, that should be
# the sign that the section exists
# section obj then supports getting all subsections
for cfg_section_name in self._parser.sections():
master_section = coreutils.get_canonical_parts(cfg_section_name)[0]
if section_name == master_section:
return PyRevitConfigSectionParser(self._parser,
master_section)
# if no match happened then raise exception
raise AttributeError('Section does not exist in config file.')
``` | ##### `remove_section(section_name)` Remove section from config. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
217
218
219
220
221
222
``` | ```md-code__content
def remove_section(self, section_name):
"""Remove section from config."""
cfg_section = self.get_section(section_name)
for cfg_subsection in cfg_section.get_subsections():
self._parser.remove_section(cfg_subsection.header)
self._parser.remove_section(cfg_section.header)
``` | ##### `reload(cfg_file_path=None)` Reload config from original or given file. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
224
225
226
227
228
229
230
231
232
233
234
``` | ```md-code__content
def reload(self, cfg_file_path=None):
"""Reload config from original or given file."""
try:
with codecs.open(cfg_file_path \
or self._cfg_file_path, 'r', 'utf-8') as cfg_file:
try:
self._parser.readfp(cfg_file)
except AttributeError:
self._parser.read_file(cfg_file)
except (OSError, IOError):
raise PyRevitIOError()
``` | ##### `save(cfg_file_path=None)` Save config to original or given file. Source code in `pyrevitlib/pyrevit/coreutils/configparser.py` | | | | --- | --- | | ```
236
237
238
239
240
241
242
243
``` | ```md-code__content
def save(self, cfg_file_path=None):
"""Save config to original or given file."""
try:
with codecs.open(cfg_file_path \
or self._cfg_file_path, 'w', 'utf-8') as cfg_file:
self._parser.write(cfg_file)
except (OSError, IOError):
raise PyRevitIOError()
``` | Back to top ## DirectContext3DServer Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/dc3dserver/#pyrevit.revit.dc3dserver) # dc3dserver DirectContext3DServer wrapper and utilities. ## Attributes ### `Edge = namedtuple('Edge', ['a', 'b', 'color'])``module-attribute` ### `Triangle = namedtuple('Triangle', ['a', 'b', 'c', 'normal', 'color'])``module-attribute` ## Classes ### `Mesh(edges, triangles)` Bases: `object` Geometry container class to generate DirectContext3DServer buffers. Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
17
18
19
20
21
22
23
24
25
26
27
28
29
30
``` | ```md-code__content
def __init__(self, edges, triangles):
if not isinstance(edges, list):
raise ValueError("List of Edges should be provided")
self.edges = edges
if not isinstance(triangles, list):
raise ValueError("List of Triangles should be provided")
self.triangles = triangles
vertices = []
for edge in self.edges:
vertices.extend([edge.a, edge.b])
for triangle in self.triangles:
vertices.extend([triangle.a, triangle.b, triangle.c])
self.vertices = vertices
``` | #### Attributes ##### `edges = edges``instance-attribute` ##### `triangles = triangles``instance-attribute` ##### `vertices = vertices``instance-attribute` #### Functions ##### `calculate_triangle_normal(a, b, c)``staticmethod` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
32
33
34
``` | ```md-code__content
@staticmethod
def calculate_triangle_normal(a, b, c):
return (c - a).CrossProduct(b - a)
``` | ##### `from_solid(doc, solid)``classmethod` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
``` | ```md-code__content
@classmethod
def from_solid(cls, doc, solid):
try:
if not isinstance(solid, DB.Solid):
raise TypeError("Provided object has to be a Revit Solid!")
triangles = []
edges = []
for face in solid.Faces:
if face.MaterialElementId == DB.ElementId.InvalidElementId:
# make it white if material is
color = DB.ColorWithTransparency(255, 255, 255, 0)
else:
material = doc.GetElement(face.MaterialElementId)
color = DB.ColorWithTransparency(
material.Color.Red,
material.Color.Green,
material.Color.Blue,
int(material.Transparency / 100 * 255)
)
face_mesh = face.Triangulate()
triangle_count = face_mesh.NumTriangles
for idx in range(triangle_count):
mesh_triangle = face_mesh.get_Triangle(idx)
if face_mesh.DistributionOfNormals == \
DB.DistributionOfNormals.OnePerFace:
normal = face_mesh.GetNormal(0)
elif face_mesh.DistributionOfNormals == \
DB.DistributionOfNormals.OnEachFacet:
normal = face_mesh.GetNormal(idx)
elif face_mesh.DistributionOfNormals == \
DB.DistributionOfNormals.AtEachPoint:
normal = (
face_mesh.GetNormal(mesh_triangle.get_Index(0)) +
face_mesh.GetNormal(mesh_triangle.get_Index(1)) +
face_mesh.GetNormal(mesh_triangle.get_Index(2))
).Normalize()
triangles.append(
Triangle(
mesh_triangle.get_Vertex(0),
mesh_triangle.get_Vertex(1),
mesh_triangle.get_Vertex(2),
normal,
color
)
)
for edge in solid.Edges:
pts = edge.Tessellate()
for idx in range(len(pts)-1):
edges.append(
Edge(
pts[idx],
pts[idx+1],
DB.ColorWithTransparency(0,0,0,0)
)
)
return cls(edges, triangles)
except:
print(traceback.format_exc())
``` | ##### `from_boundingbox(bounding_box, color, black_edges=True)``classmethod` Generates a Mesh object from the input BoundigBoxXYZ. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `bounding_box` | `BoundingBoxXYZ` | The source object. | _required_ | | `color` | `ColorWithTransparency` | The desired color. | _required_ | | `black_edges` | `bool` | To have black edges instead of the provided color.
Defaults to True. | `True` | Returns: | Type | Description | | --- | --- | | `Mesh` | The resulting Mesh | Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
``` | ```md-code__content
@classmethod
def from_boundingbox(cls, bounding_box, color, black_edges = True):
"""Generates a Mesh object from the input BoundigBoxXYZ.
Args:
bounding_box (DB.BoundingBoxXYZ): The source object.
color (DB.ColorWithTransparency): The desired color.
black_edges (bool, optional):
To have black edges instead of the provided color.
Defaults to True.
Returns:
(Mesh): The resulting Mesh
"""
try:
# get all untransformed vertices of the boundingbox
vertices = [
[
DB.XYZ(
bounding_box.Min.X,
bounding_box.Min.Y,
bounding_box.Min.Z
),
DB.XYZ(
bounding_box.Min.X,
bounding_box.Max.Y,
bounding_box.Min.Z
),
DB.XYZ(
bounding_box.Max.X,
bounding_box.Max.Y,
bounding_box.Min.Z
),
DB.XYZ(
bounding_box.Max.X,
bounding_box.Min.Y,
bounding_box.Min.Z
),
],
[
DB.XYZ(
bounding_box.Min.X,
bounding_box.Min.Y,
bounding_box.Max.Z
),
DB.XYZ(
bounding_box.Min.X,
bounding_box.Max.Y,
bounding_box.Max.Z
),
DB.XYZ(
bounding_box.Max.X,
bounding_box.Max.Y,
bounding_box.Max.Z
),
DB.XYZ(
bounding_box.Max.X,
bounding_box.Min.Y,
bounding_box.Max.Z
)
]
]
# apply it's transform if it has any
vertices = [
[bounding_box.Transform.OfPoint(pt) for pt in vertices[idx]]
for idx in range(len(vertices))
]
if black_edges:
edge_color = DB.ColorWithTransparency(0,0,0,0)
else:
edge_color = color
edges = []
# creating top and bottom face triangles
triangles = [
Triangle(
vertices[0][0],
vertices[0][2],
vertices[0][1],
Mesh.calculate_triangle_normal(
vertices[0][0],
vertices[0][2],
vertices[0][1]
),
color),
Triangle(
vertices[0][0],
vertices[0][3],
vertices[0][2],
Mesh.calculate_triangle_normal(
vertices[0][0],
vertices[0][3],
vertices[0][2]
),
color),
Triangle(
vertices[1][0],
vertices[1][1],
vertices[1][2],
Mesh.calculate_triangle_normal(
vertices[1][0],
vertices[1][1],
vertices[1][2]
),
color),
Triangle(
vertices[1][0],
vertices[1][2],
vertices[1][3],
Mesh.calculate_triangle_normal(
vertices[1][0],
vertices[1][2],
vertices[1][3]
),
color)
]
# creating edges and face triangles for the sides
for idx in range(4):
edges.extend([
Edge(vertices[0][idx], vertices[1][idx], edge_color),
Edge(vertices[0][idx], vertices[0][idx-1], edge_color),
Edge(vertices[1][idx], vertices[1][idx-1], edge_color)
])
triangles.extend([
Triangle(
vertices[0][idx],
vertices[1][idx],
vertices[0][idx-1],
Mesh.calculate_triangle_normal(
vertices[0][idx],
vertices[1][idx],
vertices[0][idx-1]
),
color),
Triangle(
vertices[1][idx],
vertices[1][idx-1],
vertices[0][idx-1],
Mesh.calculate_triangle_normal(
vertices[1][idx],
vertices[1][idx-1],
vertices[0][idx-1]
),
color)
])
return cls(edges, triangles)
except Exception:
print(traceback.format_exc())
``` | ### `Buffer(display_style, vertex_buffer, vertex_count, index_buffer, index_count, vertex_format, effect_instance, primitive_type, start, primitive_count)` Bases: `object` Buffer container for DirectContext3DServer. Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
``` | ```md-code__content
def __init__(self,
display_style,
vertex_buffer,
vertex_count,
index_buffer,
index_count,
vertex_format,
effect_instance,
primitive_type,
start,
primitive_count):
self.display_style = display_style
self.vertex_buffer = vertex_buffer
self.vertex_count = vertex_count
self.index_buffer = index_buffer
self.index_count = index_count
self.vertex_format = vertex_format
self.effect_instance = effect_instance
self.primitive_type = primitive_type
self.start = start
self.primitive_count = primitive_count
``` | #### Attributes ##### `display_style = display_style``instance-attribute` ##### `vertex_buffer = vertex_buffer``instance-attribute` ##### `vertex_count = vertex_count``instance-attribute` ##### `index_buffer = index_buffer``instance-attribute` ##### `index_count = index_count``instance-attribute` ##### `vertex_format = vertex_format``instance-attribute` ##### `effect_instance = effect_instance``instance-attribute` ##### `primitive_type = primitive_type``instance-attribute` ##### `start = start``instance-attribute` ##### `primitive_count = primitive_count``instance-attribute` #### Functions ##### `is_valid(display_style)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
273
274
275
276
277
278
279
280
``` | ```md-code__content
def is_valid(self, display_style):
return all([
self.display_style == display_style,
self.vertex_buffer.IsValid,
self.index_buffer.IsValid,
self.vertex_format.IsValid,
self.effect_instance.IsValid
])
``` | ##### `build_edge_buffer(display_style, meshes)``classmethod` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
``` | ```md-code__content
@classmethod
def build_edge_buffer(cls, display_style, meshes):
try:
if not meshes:
return
edges = [
edge for edges in [m.edges for m in meshes]
for edge in edges
]
format_bits = dc3d.VertexFormatBits.PositionColored
vertex_format = dc3d.VertexFormat(format_bits)
effect_instance = dc3d.EffectInstance(format_bits)
vertex_count = (dc3d.VertexPositionColored.GetSizeInFloats()
* len(edges) * 2)
vertex_buffer = dc3d.VertexBuffer(vertex_count)
index_count = dc3d.IndexLine.GetSizeInShortInts() * len(edges)
index_buffer = dc3d.IndexBuffer(index_count)
vertex_buffer.Map(vertex_count)
index_buffer.Map(index_count)
vertex_stream_pos = vertex_buffer.GetVertexStreamPositionColored()
index_stream_pos = index_buffer.GetIndexStreamLine()
for edge in edges:
edge_index = edges.index(edge)
first_idx = edge_index * 2
vertex_stream_pos.AddVertex(dc3d.VertexPositionColored(
edge.a, edge.color
))
vertex_stream_pos.AddVertex(dc3d.VertexPositionColored(
edge.b, edge.color
))
index_stream_pos.AddLine(dc3d.IndexLine(
first_idx,
first_idx + 1
))
vertex_buffer.Unmap()
index_buffer.Unmap()
return cls(
display_style,
vertex_buffer,
vertex_count,
index_buffer,
index_count,
vertex_format,
effect_instance,
dc3d.PrimitiveType.LineList,
0,
len(edges)
)
except:
print(traceback.format_exc())
``` | ##### `build_triangle_buffer(display_style, meshes, transparent=False)``classmethod` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
``` | ```md-code__content
@classmethod
def build_triangle_buffer(cls, display_style, meshes, transparent = False):
try:
if not meshes:
return
triangles = [
triangle for triangles in [m.triangles for m in meshes]
for triangle in triangles
if transparent == (triangle.color.GetTransparency() > 0)
]
if not triangles:
return
shaded = any([
display_style == DB.DisplayStyle.Shading,
display_style == DB.DisplayStyle.ShadingWithEdges
])
format_bits = dc3d.VertexFormatBits.PositionNormalColored
vertex_format = dc3d.VertexFormat(format_bits)
if shaded:
effect_instance = dc3d.EffectInstance(
dc3d.VertexFormatBits.PositionNormalColored
)
else:
effect_instance = dc3d.EffectInstance(
dc3d.VertexFormatBits.PositionColored
)
vertex_count = (dc3d.VertexPositionNormalColored.GetSizeInFloats()
* len(triangles) * 3)
vertex_buffer = dc3d.VertexBuffer(vertex_count)
index_count = (dc3d.IndexTriangle.GetSizeInShortInts()
* len(triangles))
index_buffer = dc3d.IndexBuffer(index_count)
vertex_buffer.Map(vertex_count)
index_buffer.Map(index_count)
vertex_stream_pos = (vertex_buffer
.GetVertexStreamPositionNormalColored())
index_stream_pos = index_buffer.GetIndexStreamTriangle()
for triangle in triangles:
if display_style == DB.DisplayStyle.HLR:
color = DB.ColorWithTransparency(
255, 255, 255, triangle.color.GetTransparency()
)
else:
color = triangle.color
normal = triangle.normal
triangle_index = triangles.index(triangle)
first_idx = triangle_index * 3
vertex_stream_pos.AddVertex(dc3d.VertexPositionNormalColored(
triangle.a, normal, color
))
vertex_stream_pos.AddVertex(dc3d.VertexPositionNormalColored(
triangle.b, normal, color
))
vertex_stream_pos.AddVertex(dc3d.VertexPositionNormalColored(
triangle.c, normal, color
))
index_stream_pos.AddTriangle(dc3d.IndexTriangle(
first_idx,
first_idx + 1,
first_idx + 2
))
vertex_buffer.Unmap()
index_buffer.Unmap()
return cls(
display_style,
vertex_buffer,
vertex_count,
index_buffer,
index_count,
vertex_format,
effect_instance,
dc3d.PrimitiveType.TriangleList,
0,
len(triangles)
)
except:
print(traceback.format_exc())
``` | ##### `flush()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
426
427
428
429
430
431
432
433
434
435
436
437
``` | ```md-code__content
def flush(self):
dc3d.DrawContext.FlushBuffer(
self.vertex_buffer,
self.vertex_count,
self.index_buffer,
self.index_count,
self.vertex_format,
self.effect_instance,
self.primitive_type,
self.start,
self.primitive_count
)
``` | ### `Server(guid=None, uidoc=None, name='pyRevit DirectContext3DServer', description='Displaying temporary geometries', vendor_id='pyRevit', register=True)` Bases: `IDirectContext3DServer` A generic DirectContext3dServer interface implementation. Initalize a DirectContext3DServer instance. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `guid` | `Guid` | The guid of the server, auto-generated if None.
Defaults to None. | `None` | | `uidoc` | `UIDocument` | Required only, if the geometry is Document specific.
Defaults to None. | `None` | | `name` | `str` | The name of the server.
Defaults to "pyRevit DirectContext3DServer". | `'pyRevit DirectContext3DServer'` | | `description` | `str` | The descritpion of the server.
Defaults to "Displaying temporary geometries". | `'Displaying temporary geometries'` | | `vendor_id` | `str` | The name of the vendor. Defaults to "pyRevit". | `'pyRevit'` | | `register` | `bool` | To register the server on initalization.
Defaults to True. | `True` | Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
``` | ```md-code__content
def __init__(
self,
guid=None,
uidoc=None,
name="pyRevit DirectContext3DServer",
description="Displaying temporary geometries",
vendor_id="pyRevit",
register=True
):
"""Initalize a DirectContext3DServer instance.
Args:
guid (System.Guid, optional):
The guid of the server, auto-generated if None.
Defaults to None.
uidoc (UI.UIDocument, optional):
Required only, if the geometry is Document specific.
Defaults to None.
name (str, optional):
The name of the server.
Defaults to "pyRevit DirectContext3DServer".
description (str, optional):
The descritpion of the server.
Defaults to "Displaying temporary geometries".
vendor_id (str, optional):
The name of the vendor. Defaults to "pyRevit".
register (bool, optional):
To register the server on initalization.
Defaults to True.
"""
try:
if guid is None:
self.guid = Guid.NewGuid()
else:
self.guid = guid
self.uidoc = uidoc
self.name = name
self.description = description
self.vendor_id = vendor_id
self.meshes = []
self._line_buffer = None
self._transparent_buffer = None
self._opaque_buffer = None
self.enabled_view_types = [
DB.ViewType.ThreeD,
DB.ViewType.Elevation,
DB.ViewType.Section,
DB.ViewType.FloorPlan,
DB.ViewType.CeilingPlan,
DB.ViewType.EngineeringPlan
]
if register:
self.add_server()
except Exception:
print(traceback.format_exc())
``` | #### Attributes ##### `guid = Guid.NewGuid()``instance-attribute` ##### `uidoc = uidoc``instance-attribute` ##### `name = name``instance-attribute` ##### `description = description``instance-attribute` ##### `vendor_id = vendor_id``instance-attribute` ##### `enabled_view_types = [DB.ViewType.ThreeD, DB.ViewType.Elevation, DB.ViewType.Section, DB.ViewType.FloorPlan, DB.ViewType.CeilingPlan, DB.ViewType.EngineeringPlan]``instance-attribute` ##### `meshes``property``writable` The container for the source geometries. #### Functions ##### `CanExecute(view)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
501
502
503
504
505
506
``` | ```md-code__content
def CanExecute(self, view):
if any(vt == view.ViewType for vt in self.enabled_view_types):
if self.uidoc is not None:
return self.uidoc.Document.Equals(view.Document)
return True
return False
``` | ##### `GetApplicationId()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
508
509
``` | ```md-code__content
def GetApplicationId(self):
return ""
``` | ##### `GetBoundingBox(view)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
``` | ```md-code__content
def GetBoundingBox(self, view):
try:
if not self.meshes:
return
vertices = [
vertex for vertices in [m.vertices for m in self.meshes]
for vertex in vertices
]
if not len(vertices) > 1:
return
outline = DB.Outline(vertices[0], vertices[1])
for idx in range(2, len(vertices)):
outline.AddPoint(vertices[idx])
return outline
except:
print(traceback.format_exc())
``` | ##### `GetDescription()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
533
534
``` | ```md-code__content
def GetDescription(self):
return self.description
``` | ##### `GetName()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
536
537
``` | ```md-code__content
def GetName(self):
return self.name
``` | ##### `GetServerId()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
539
540
``` | ```md-code__content
def GetServerId(self):
return self.guid
``` | ##### `GetServiceId()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
542
543
544
``` | ```md-code__content
def GetServiceId(self):
return ( es.ExternalServices
.BuiltInExternalServices.DirectContext3DService)
``` | ##### `GetSourceId()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
546
547
``` | ```md-code__content
def GetSourceId(self):
return ""
``` | ##### `GetVendorId()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
549
550
``` | ```md-code__content
def GetVendorId(self):
return self.vendor_id
``` | ##### `UsesHandles()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
552
553
``` | ```md-code__content
def UsesHandles(self):
return False
``` | ##### `UseInTransparentPass(view)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
555
556
``` | ```md-code__content
def UseInTransparentPass(self, view):
return True
``` | ##### `RenderScene(view, display_style)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
``` | ```md-code__content
def RenderScene(self, view, display_style):
try:
if self.meshes:
if all([
self._line_buffer is None,
self._opaque_buffer is None,
self._transparent_buffer is None
]) or any([
(self._line_buffer is not None
and not self._line_buffer.is_valid(display_style)),
(self._opaque_buffer is not None
and not self._opaque_buffer.is_valid(display_style)),
(self._transparent_buffer is not None
and not self._transparent_buffer.is_valid(display_style))
]):
self.update_buffers(display_style)
if dc3d.DrawContext.IsTransparentPass():
if (self._transparent_buffer is not None
and display_style != DB.DisplayStyle.Wireframe):
self._transparent_buffer.flush()
else:
if (self._opaque_buffer is not None
and display_style != DB.DisplayStyle.Wireframe):
self._opaque_buffer.flush()
if (self._line_buffer is not None
and display_style != DB.DisplayStyle.Rendering
and display_style != DB.DisplayStyle.Shading):
self._line_buffer.flush()
except:
print(traceback.format_exc())
``` | ##### `add_server()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
607
608
609
610
611
612
613
614
615
``` | ```md-code__content
def add_server(self):
service = es.ExternalServiceRegistry.GetService(self.GetServiceId())
# check for leftovers
if service.IsRegisteredServerId(self.GetServerId()):
self.remove_server()
service.AddServer(self)
server_ids = service.GetActiveServerIds()
server_ids.Add(self.GetServerId())
service.SetActiveServers(server_ids)
``` | ##### `remove_server()` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
617
618
619
620
``` | ```md-code__content
def remove_server(self):
service = es.ExternalServiceRegistry.GetService(self.GetServiceId())
if service.IsRegisteredServerId(self.GetServerId()):
service.RemoveServer(self.GetServerId())
``` | ##### `update_buffers(display_style)` Source code in `pyrevitlib/pyrevit/revit/dc3dserver.py` | | | | --- | --- | | ```
622
623
624
625
626
627
``` | ```md-code__content
def update_buffers(self, display_style):
self._line_buffer = Buffer.build_edge_buffer(display_style, self.meshes)
self._opaque_buffer = Buffer.build_triangle_buffer(
display_style, self.meshes, transparent=False)
self._transparent_buffer = Buffer.build_triangle_buffer(
display_style, self.meshes, transparent=True)
``` | Back to top ## pyRevit Session Info [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/loader/sessioninfo/#pyrevit.loader.sessioninfo) # sessioninfo Manage information about pyRevit sessions. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `RuntimeInfo = namedtuple('RuntimeInfo', ['pyrevit_version', 'engine_version', 'host_version'])``module-attribute` Session runtime information tuple. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrevit_version` | `str` | formatted pyRevit version | _required_ | | `engine_version` | `int` | active IronPython engine version | _required_ | | `host_version` | `str` | Current Revit version | _required_ | ## Functions ### `setup_runtime_vars()` Setup runtime environment variables with session information. Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
``` | ```md-code__content
def setup_runtime_vars():
"""Setup runtime environment variables with session information."""
# set pyrevit version
pyrvt_ver = versionmgr.get_pyrevit_version().get_formatted()
envvars.set_pyrevit_env_var(envvars.VERSION_ENVVAR, pyrvt_ver)
# set app version env var
if HOST_APP.is_newer_than(2017):
envvars.set_pyrevit_env_var(envvars.APPVERSION_ENVVAR,
HOST_APP.subversion)
else:
envvars.set_pyrevit_env_var(envvars.APPVERSION_ENVVAR,
HOST_APP.version)
# set ironpython engine version env var
attachment = user_config.get_current_attachment()
if attachment and attachment.Clone:
envvars.set_pyrevit_env_var(envvars.CLONENAME_ENVVAR,
attachment.Clone.Name)
envvars.set_pyrevit_env_var(envvars.IPYVERSION_ENVVAR,
str(attachment.Engine.Version))
else:
mlogger.debug('Can not determine attachment.')
envvars.set_pyrevit_env_var(envvars.CLONENAME_ENVVAR, "Unknown")
envvars.set_pyrevit_env_var(envvars.IPYVERSION_ENVVAR, "0")
# set cpython engine version env var
cpyengine = user_config.get_active_cpython_engine()
if cpyengine:
envvars.set_pyrevit_env_var(envvars.CPYVERSION_ENVVAR,
str(cpyengine.Version))
else:
envvars.set_pyrevit_env_var(envvars.CPYVERSION_ENVVAR, "0")
# set a list of important assemblies
# this is required for dotnet script execution
set_loaded_pyrevit_referenced_modules(
runtime.get_references()
)
``` | ### `get_runtime_info()` Return runtime information tuple. Returns: | Type | Description | | --- | --- | | `RuntimeInfo` | runtime info tuple | Examples: ```md-code__content sessioninfo.get_runtime_info() ``` Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
``` | ````md-code__content
def get_runtime_info():
"""Return runtime information tuple.
Returns:
(RuntimeInfo): runtime info tuple
Examples:
```python
sessioninfo.get_runtime_info()
```
"""
# FIXME: add example output
return RuntimeInfo(
pyrevit_version=envvars.get_pyrevit_env_var(envvars.VERSION_ENVVAR),
engine_version=envvars.get_pyrevit_env_var(envvars.IPYVERSION_ENVVAR),
host_version=envvars.get_pyrevit_env_var(envvars.APPVERSION_ENVVAR)
)
```` | ### `set_session_uuid(uuid_str)` Set session uuid on environment variable. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `uuid_str` | `str` | session uuid string | _required_ | Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
94
95
96
97
98
99
100
``` | ```md-code__content
def set_session_uuid(uuid_str):
"""Set session uuid on environment variable.
Args:
uuid_str (str): session uuid string
"""
envvars.set_pyrevit_env_var(envvars.SESSIONUUID_ENVVAR, uuid_str)
``` | ### `get_session_uuid()` Read session uuid from environment variable. Returns: | Type | Description | | --- | --- | | `str` | session uuid string | Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
103
104
105
106
107
108
109
``` | ```md-code__content
def get_session_uuid():
"""Read session uuid from environment variable.
Returns:
(str): session uuid string
"""
return envvars.get_pyrevit_env_var(envvars.SESSIONUUID_ENVVAR)
``` | ### `new_session_uuid()` Create a new uuid for a pyRevit session. Returns: | Type | Description | | --- | --- | | `str` | session uuid string | Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
112
113
114
115
116
117
118
119
120
``` | ```md-code__content
def new_session_uuid():
"""Create a new uuid for a pyRevit session.
Returns:
(str): session uuid string
"""
uuid_str = safe_strtype(coreutils.new_uuid())
set_session_uuid(uuid_str)
return uuid_str
``` | ### `get_loaded_pyrevit_assemblies()` Return list of loaded pyRevit assemblies from environment variable. Returns: | Type | Description | | --- | --- | | `list[str]` | list of loaded assemblies | Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
123
124
125
126
127
128
129
130
131
132
133
134
``` | ```md-code__content
def get_loaded_pyrevit_assemblies():
"""Return list of loaded pyRevit assemblies from environment variable.
Returns:
(list[str]): list of loaded assemblies
"""
# FIXME: verify and document return type
loaded_assms_str = envvars.get_pyrevit_env_var(envvars.LOADEDASSMS_ENVVAR)
if loaded_assms_str:
return loaded_assms_str.split(coreutils.DEFAULT_SEPARATOR)
else:
return []
``` | ### `set_loaded_pyrevit_assemblies(loaded_assm_name_list)` Set the environment variable with list of loaded assemblies. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `loaded_assm_name_list` | `list[str]` | list of assembly names | _required_ | Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
137
138
139
140
141
142
143
144
145
146
``` | ```md-code__content
def set_loaded_pyrevit_assemblies(loaded_assm_name_list):
"""Set the environment variable with list of loaded assemblies.
Args:
loaded_assm_name_list (list[str]): list of assembly names
"""
envvars.set_pyrevit_env_var(
envvars.LOADEDASSMS_ENVVAR,
coreutils.DEFAULT_SEPARATOR.join(loaded_assm_name_list)
)
``` | ### `get_loaded_pyrevit_referenced_modules()` Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
149
150
151
152
153
154
``` | ```md-code__content
def get_loaded_pyrevit_referenced_modules():
loaded_assms_str = envvars.get_pyrevit_env_var(envvars.REFEDASSMS_ENVVAR)
if loaded_assms_str:
return set(loaded_assms_str.split(coreutils.DEFAULT_SEPARATOR))
else:
return set()
``` | ### `set_loaded_pyrevit_referenced_modules(loaded_assm_name_list)` Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
157
158
159
160
161
``` | ```md-code__content
def set_loaded_pyrevit_referenced_modules(loaded_assm_name_list):
envvars.set_pyrevit_env_var(
envvars.REFEDASSMS_ENVVAR,
coreutils.DEFAULT_SEPARATOR.join(loaded_assm_name_list)
)
``` | ### `update_loaded_pyrevit_referenced_modules(loaded_assm_name_list)` Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
164
165
166
167
``` | ```md-code__content
def update_loaded_pyrevit_referenced_modules(loaded_assm_name_list):
loaded_modules = get_loaded_pyrevit_referenced_modules()
loaded_modules.update(loaded_assm_name_list)
set_loaded_pyrevit_referenced_modules(loaded_modules)
``` | ### `report_env()` Report python version, home directory, config file, etc. Source code in `pyrevitlib/pyrevit/loader/sessioninfo.py` | | | | --- | --- | | ```
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
``` | ```md-code__content
def report_env():
"""Report python version, home directory, config file, etc."""
# run diagnostics
system_diag()
# get python version that includes last commit hash
mlogger.info('pyRevit version: %s - with :growing_heart: in %s',
envvars.get_pyrevit_env_var(envvars.VERSION_ENVVAR),
about.get_pyrevit_about().madein)
if user_config.rocket_mode:
mlogger.info('pyRevit Rocket Mode enabled. :rocket:')
mlogger.info('Host is %s pid: %s', HOST_APP.pretty_name, HOST_APP.proc_id)
# ipy 2.7.10 has a new line in its sys.version :rolling-eyes-emoji:
mlogger.info('Running on: %s', sys.version.replace('\n', ' '))
mlogger.info('User is: %s', HOST_APP.username)
mlogger.info('Home Directory is: %s', HOME_DIR)
mlogger.info('Session uuid is: %s', get_session_uuid())
mlogger.info('Runtime assembly is: %s', runtime.RUNTIME_ASSM_NAME)
mlogger.info('Config file is (%s): %s',
user_config.config_type, user_config.config_file)
``` | Back to top ## Revit Server Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/serverutils/#pyrevit.revit.serverutils) # serverutils Helper functions for working with revit server. ## Attributes ### `MODEL_HISTORY_SQLDB = '/Data/Model.db3'``module-attribute` ### `SyncHistory = namedtuple('SyncHistory', ['index', 'userid', 'timestamp'])``module-attribute` namedtuple for model sync history data in revit server Attributes: | Name | Type | Description | | --- | --- | --- | | `index` | `int` | row index in history db | | `userid` | `str` | user identifier | | `timestamp` | `str` | time stamp string (e.g. "2017-12-13 19:56:20") | ## Functions ### `get_server_path(doc, path_dict)` Return file path of a model hosted on revit server. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | revit document object | _required_ | | `path_dict` | `dict` | dict of RSN paths and their directory paths | _required_ | Examples: ```md-code__content rsn_paths = {'RSN://SERVERNAME': '//servername/filestore'} get_server_path(doc, rsn_paths) ``` "//servername/filestore/path/to/model.rvt" Source code in `pyrevitlib/pyrevit/revit/serverutils.py` | | | | --- | --- | | ```
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
``` | ````md-code__content
def get_server_path(doc, path_dict):
"""Return file path of a model hosted on revit server.
Args:
doc (Document): revit document object
path_dict (dict): dict of RSN paths and their directory paths
Examples:
```python
rsn_paths = {'RSN://SERVERNAME': '//servername/filestore'}
get_server_path(doc, rsn_paths)
```
"//servername/filestore/path/to/model.rvt"
"""
model_path = doc.GetWorksharingCentralModelPath()
path = DB.ModelPathUtils.ConvertModelPathToUserVisiblePath(model_path)
for key, value in path_dict.items():
path = path.replace(key, value)
return path
```` | ### `get_model_sync_history(server_path)` Read model sync history from revit server sqlite history file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `server_path` | `str` | directory path of revit server filestore | _required_ | Returns: | Type | Description | | --- | --- | | `list[SyncHistory]` | list of SyncHistory instances | Examples: ```md-code__content get_model_sync_history("//servername/path/to/model.rvt") ``` \[SyncHistory(index=498, userid="user",\ timestamp="2017-12-13 19:56:20")\] Source code in `pyrevitlib/pyrevit/revit/serverutils.py` | | | | --- | --- | | ```
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
``` | ````md-code__content
def get_model_sync_history(server_path):
"""Read model sync history from revit server sqlite history file.
Args:
server_path (str): directory path of revit server filestore
Returns:
(list[SyncHistory]): list of SyncHistory instances
Examples:
```python
get_model_sync_history("//servername/path/to/model.rvt")
```
[SyncHistory(index=498, userid="user",
timestamp="2017-12-13 19:56:20")]
"""
db_path = server_path + MODEL_HISTORY_SQLDB
conn = sqlite3.connect(db_path)
sync_hist = []
for row in conn.execute("SELECT * FROM ModelHistory"):
sync_hist.append(SyncHistory(index=int(row[0]),
userid=row[1],
timestamp=row[2][:-1]))
return sync_hist
```` | Back to top ## Python Helper Functions [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/pyutils/#pyrevit.coreutils.pyutils) # pyutils Helper functions for python. Examples: ```md-code__content from pyrevit.coreutils import pyutils pyutils.safe_cast('string', int, 0) ``` ## Attributes ## Classes ### `DefaultOrderedDict(default_factory=None, *a, **kw)` Bases: `OrderedDict` Ordered dictionary with default type. This is similar to defaultdict and maintains the order of items added to it so in that regards it functions similar to OrderedDict. Examples: ```md-code__content from pyrevit.coreutils import pyutils od = pyutils.DefaultOrderedDict(list) od['A'] = [1, 2, 3] od['B'] = [4, 5, 6] od['C'].extend([7, 8, 9]) for k, v in od.items(): print(k, v) ``` ('A', \[1, 2, 3\]) ('B', \[4, 5, 6\]) ('C', \[7, 8, 9\]) Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
42
43
44
45
46
47
48
``` | ```md-code__content
def __init__(self, default_factory=None, *a, **kw): #pylint: disable=W1113
if (default_factory is not None \
and not isinstance(default_factory, Callable)):
raise TypeError('first argument must be callable')
OrderedDict.__init__(self, *a, **kw)
self.default_factory = default_factory
``` | #### Attributes ##### `default_factory = default_factory``instance-attribute` #### Functions ##### `copy()` Copy the dictionary. Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
69
70
71
``` | ```md-code__content
def copy(self):
"""Copy the dictionary."""
return self.__copy__()
``` | ## Functions ### `pairwise(iterable, step=2)` Iterate through items in pairs. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `iterable` | `iterable` | any iterable object | _required_ | | `step` | `int` | number of steps to move when making pairs | `2` | Returns: | Type | Description | | --- | --- | | `Iterable[Any]` | list of pairs | Examples: ```md-code__content pairwise([1, 2, 3, 4, 5]) ``` \[(1, 2), (3, 4)\] # 5 can not be paired ```md-code__content pairwise([1, 2, 3, 4, 5, 6]) ``` \[(1, 2), (3, 4), (5, 6)\] ```md-code__content pairwise([1, 2, 3, 4, 5, 6], step=1) ``` \[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)\] Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
``` | ````md-code__content
def pairwise(iterable, step=2):
"""Iterate through items in pairs.
Args:
iterable (iterable): any iterable object
step (int): number of steps to move when making pairs
Returns:
(Iterable[Any]): list of pairs
Examples:
```python
pairwise([1, 2, 3, 4, 5])
```
[(1, 2), (3, 4)] # 5 can not be paired
```python
pairwise([1, 2, 3, 4, 5, 6])
```
[(1, 2), (3, 4), (5, 6)]
```python
pairwise([1, 2, 3, 4, 5, 6], step=1)
```
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
"""
if step == 1:
a, b = tee(iterable)
next(b, None)
return zip(a, b)
elif step == 2:
a = iter(iterable)
return zip(a, a)
```` | ### `safe_cast(val, to_type, default=None)` Convert value to type gracefully. This method basically calls to\_type(value) and returns the default if exception occurs. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `val` | `any` | value to be converted | _required_ | | `to_type` | `type` | target type | _required_ | | `default` | `any` | value to rerun on conversion exception | `None` | Examples: ```md-code__content safe_cast('name', int, default=0) ``` 0 Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
``` | ````md-code__content
def safe_cast(val, to_type, default=None):
"""Convert value to type gracefully.
This method basically calls to_type(value) and returns the default
if exception occurs.
Args:
val (any): value to be converted
to_type (type): target type
default (any): value to rerun on conversion exception
Examples:
```python
safe_cast('name', int, default=0)
```
0
"""
try:
return to_type(val)
except (ValueError, TypeError):
return default
```` | ### `isnumber(token)` Verify if given string token is int or float. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `token` | `str` | string value | _required_ | Returns: | Type | Description | | --- | --- | | `bool` | True of token is int or float | Examples: ```md-code__content isnumber('12.3') ``` True Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
``` | ````md-code__content
def isnumber(token):
"""Verify if given string token is int or float.
Args:
token (str): string value
Returns:
(bool): True of token is int or float
Examples:
```python
isnumber('12.3')
```
True
"""
if token:
return re.match("^-*[0-9.]+?$", token) is not None
else:
return False
```` | ### `compare_lists(x, y)` Compare two lists. See: https://stackoverflow.com/a/10872313/2350244 Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `x` | `list` | first list | _required_ | | `y` | `list` | second list | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
162
163
164
165
166
167
168
169
170
171
``` | ```md-code__content
def compare_lists(x, y):
"""Compare two lists.
See: https://stackoverflow.com/a/10872313/2350244
Args:
x (list): first list
y (list): second list
"""
return len(frozenset(x).difference(y)) == 0
``` | ### `merge(d1, d2)` Merge d2 into d1. d2 dict values are recursively merged into d1 dict values other d2 values are added to d1 dict values with the same key new d2 values are added to d1 d2 values override other d1 values Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `d1` | `dict` | dict to be updated | _required_ | | `d2` | `dict` | dict to be merge into d1 | _required_ | Returns: | Type | Description | | --- | --- | | `dict[Any, Any]` | updated d1 | Examples: ```md-code__content d1 = {1: 1, 2: "B" , 3: {1:"A", 2:"B"}, 4: "b" , 5: ["a", "b"]} d2 = {1: 1, 2: {1:"A"}, 3: {1:"S", 3:"C"}, 4: ["a"], 5: ["c"]} merge(d1, d2) ``` { 1:1, 2:{1:'A', 2:'B'}, 3:{1:'S', 2:'B', 3:'C'}, 4:\['a','b'\], 5: \['c', 'a', 'b'\] } Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
``` | ````md-code__content
def merge(d1, d2):
"""Merge d2 into d1.
d2 dict values are recursively merged into d1 dict values
other d2 values are added to d1 dict values with the same key
new d2 values are added to d1
d2 values override other d1 values
Args:
d1 (dict): dict to be updated
d2 (dict): dict to be merge into d1
Returns:
(dict[Any, Any]): updated d1
Examples:
```python
d1 = {1: 1, 2: "B" , 3: {1:"A", 2:"B"}, 4: "b" , 5: ["a", "b"]}
d2 = {1: 1, 2: {1:"A"}, 3: {1:"S", 3:"C"}, 4: ["a"], 5: ["c"]}
merge(d1, d2)
```
{ 1:1,
2:{1:'A', 2:'B'},
3:{1:'S', 2:'B', 3:'C'},
4:['a','b'],
5: ['c', 'a', 'b']
}
"""
if not (isinstance(d1, dict) and isinstance(d2, dict)):
raise Exception('Both inputs must be of type dict')
for key, new_value in d2.items():
if key in d1:
old_value = d1[key]
if isinstance(new_value, dict):
if isinstance(old_value, dict):
merge(old_value, new_value)
else:
new_dict = copy.deepcopy(new_value)
new_dict[key] = old_value
d1[key] = new_dict
elif isinstance(old_value, dict):
old_value[key] = new_value
elif isinstance(new_value, list):
new_list = copy.deepcopy(new_value)
if isinstance(old_value, list):
new_list.extend(old_value)
else:
if old_value not in new_value:
new_list.append(old_value)
d1[key] = new_list
elif isinstance(old_value, list):
if new_value not in old_value:
old_value.append(new_value)
else:
d1[key] = new_value
else:
d1[key] = new_value
return d1
```` | ### `almost_equal(a, b, rnd=5)` Check if two numerical values almost equal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `a` | `float` | value a | _required_ | | `b` | `float` | value b | _required_ | | `rnd` | `int` | n digits after comma. Defaults to 5. | `5` | Returns: | Type | Description | | --- | --- | | `bool` | True if almost equal | Source code in `pyrevitlib/pyrevit/coreutils/pyutils.py` | | | | --- | --- | | ```
235
236
237
238
239
240
241
242
243
244
245
246
``` | ```md-code__content
def almost_equal(a, b, rnd=5):
"""Check if two numerical values almost equal.
Args:
a (float): value a
b (float): value b
rnd (int, optional): n digits after comma. Defaults to 5.
Returns:
(bool): True if almost equal
"""
return a == b or int(a*10**rnd) == int(b*10**rnd)
``` | Back to top ## Revit Ribbon Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/ribbon/#pyrevit.coreutils.ribbon) # ribbon Base module to interact with Revit ribbon. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `PYREVIT_TAB_IDENTIFIER = 'pyrevit_tab'``module-attribute` ### `ICON_SMALL = 16``module-attribute` ### `ICON_MEDIUM = 24``module-attribute` ### `ICON_LARGE = 32``module-attribute` ### `DEFAULT_DPI = 96``module-attribute` ### `DEFAULT_TOOLTIP_IMAGE_FORMAT = '.png'``module-attribute` ### `DEFAULT_TOOLTIP_VIDEO_FORMAT = '.swf'``module-attribute` ## Classes ### `PyRevitUIError` Bases: `PyRevitException` Common base class for all pyRevit ui-related exceptions. #### Attributes ##### `msg``property` Return exception message. ### `ButtonIcons(image_file)` Bases: `object` pyRevit ui element icon. Upon init, this type reads the given image file into an io stream and releases the os lock on the file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `image_file` | `str` | image file path to be used as icon | _required_ | Attributes: | Name | Type | Description | | --- | --- | --- | | `icon_file_path` | `str` | icon image file path | | `filestream` | `FileStream` | io stream containing image binary data | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
95
96
97
98
99
100
``` | ```md-code__content
def __init__(self, image_file):
self.icon_file_path = image_file
self.check_icon_size()
self.filestream = IO.FileStream(image_file,
IO.FileMode.Open,
IO.FileAccess.Read)
``` | #### Attributes ##### `icon_file_path = image_file``instance-attribute` ##### `filestream = IO.FileStream(image_file, IO.FileMode.Open, IO.FileAccess.Read)``instance-attribute` ##### `small_bitmap``property` Resamples image and creates bitmap for size :obj: `ICON_SMALL`. Returns: | Type | Description | | --- | --- | | `BitmapSource` | object containing image data at given size | ##### `medium_bitmap``property` Resamples image and creates bitmap for size :obj: `ICON_MEDIUM`. Returns: | Type | Description | | --- | --- | | `BitmapSource` | object containing image data at given size | ##### `large_bitmap``property` Resamples image and creates bitmap for size :obj: `ICON_LARGE`. Returns: | Type | Description | | --- | --- | | `BitmapSource` | object containing image data at given size | #### Functions ##### `recolour(image_data, size, stride, color)``staticmethod` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
``` | ```md-code__content
@staticmethod
def recolour(image_data, size, stride, color):
# FIXME: needs doc, and argument types
# ButtonIcons.recolour(image_data, image_size, stride, 0x8e44ad)
step = stride / size
for i in range(0, stride, step):
for j in range(0, stride, step):
idx = (i * size) + j
# R = image_data[idx+2]
# G = image_data[idx+1]
# B = image_data[idx]
# luminance = (0.299*R + 0.587*G + 0.114*B)
image_data[idx] = color >> 0 & 0xff # blue
image_data[idx+1] = color >> 8 & 0xff # green
image_data[idx+2] = color >> 16 & 0xff # red
``` | ##### `check_icon_size()` Verify icon size is within acceptable range. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
118
119
120
121
122
123
124
125
126
127
``` | ```md-code__content
def check_icon_size(self):
"""Verify icon size is within acceptable range."""
image = System.Drawing.Image.FromFile(self.icon_file_path)
image_size = max(image.Width, image.Height)
if image_size > 96:
mlogger.warning('Icon file is too large. Large icons adversely '
'affect the load time since they need to be '
'processed and adjusted for screen scaling. '
'Keep icons at max 96x96 pixels: %s',
self.icon_file_path)
``` | ##### `create_bitmap(icon_size)` Resamples image and creates bitmap for the given size. Icons are assumed to be square. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `icon_size` | `int` | icon size (width or height) | _required_ | Returns: | Type | Description | | --- | --- | | `BitmapSource` | object containing image data at given size | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
``` | ```md-code__content
def create_bitmap(self, icon_size):
"""Resamples image and creates bitmap for the given size.
Icons are assumed to be square.
Args:
icon_size (int): icon size (width or height)
Returns:
(Imaging.BitmapSource): object containing image data at given size
"""
mlogger.debug('Creating %sx%s bitmap from: %s',
icon_size, icon_size, self.icon_file_path)
adjusted_icon_size = icon_size * 2
adjusted_dpi = DEFAULT_DPI * 2
screen_scaling = HOST_APP.proc_screen_scalefactor
self.filestream.Seek(0, IO.SeekOrigin.Begin)
base_image = Imaging.BitmapImage()
base_image.BeginInit()
base_image.StreamSource = self.filestream
base_image.DecodePixelHeight = int(adjusted_icon_size * screen_scaling)
base_image.EndInit()
self.filestream.Seek(0, IO.SeekOrigin.Begin)
image_size = base_image.PixelWidth
image_format = base_image.Format
image_byte_per_pixel = int(base_image.Format.BitsPerPixel / 8)
palette = base_image.Palette
stride = int(image_size * image_byte_per_pixel)
array_size = stride * image_size
image_data = System.Array.CreateInstance(System.Byte, array_size)
base_image.CopyPixels(image_data, stride, 0)
scaled_size = int(adjusted_icon_size * screen_scaling)
scaled_dpi = int(adjusted_dpi * screen_scaling)
bitmap_source = \
Imaging.BitmapSource.Create(scaled_size, scaled_size,
scaled_dpi, scaled_dpi,
image_format,
palette,
image_data,
stride)
return bitmap_source
``` | ### `GenericPyRevitUIContainer()` Bases: `object` Common type for all pyRevit ui containers. Attributes: | Name | Type | Description | | --- | --- | --- | | `name` | `str` | container name | | `itemdata_mode` | `bool` | if container is wrapping UI.\*ItemData | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
211
212
213
214
215
216
217
218
``` | ```md-code__content
def __init__(self):
self.name = ''
self._rvtapi_object = None
self._sub_pyrvt_components = OrderedDict()
self.itemdata_mode = False
self._dirty = False
self._visible = None
self._enabled = None
``` | #### Attributes ##### `name = ''``instance-attribute` ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
354
355
356
357
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return False
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `activate()` Activate this container in ui. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
410
411
412
413
414
415
416
417
``` | ```md-code__content
def activate(self):
"""Activate this container in ui."""
try:
self.enabled = True
self.visible = True
self._dirty = True
except Exception:
raise PyRevitUIError('Can not activate: {}'.format(self))
``` | ##### `deactivate()` Deactivate this container in ui. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
419
420
421
422
423
424
425
426
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui."""
try:
self.enabled = False
self.visible = False
self._dirty = True
except Exception:
raise PyRevitUIError('Can not deactivate: {}'.format(self))
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ### `GenericRevitNativeUIContainer()` Bases: `GenericPyRevitUIContainer` Common base type for native Revit API UI containers. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
515
516
``` | ```md-code__content
def __init__(self):
GenericPyRevitUIContainer.__init__(self)
``` | #### Attributes ##### `name = ''``instance-attribute` ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
518
519
520
521
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return True
``` | ##### `activate()` Activate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
523
524
525
526
527
528
529
``` | ```md-code__content
def activate(self):
"""Activate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
return self.deactivate()
``` | ##### `deactivate()` Deactivate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
raise PyRevitUIError('Can not de/activate native item: {}'
.format(self))
``` | ### `RevitNativeRibbonButton(adwnd_ribbon_button)` Bases: `GenericRevitNativeUIContainer` Revit API UI native ribbon button. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
543
544
545
546
547
548
549
``` | ```md-code__content
def __init__(self, adwnd_ribbon_button):
GenericRevitNativeUIContainer.__init__(self)
self.name = \
safe_strtype(adwnd_ribbon_button.AutomationName)\
.replace('\r\n', ' ')
self._rvtapi_object = adwnd_ribbon_button
``` | #### Attributes ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. ##### `name = safe_strtype(adwnd_ribbon_button.AutomationName).replace('\r\n', ' ')``instance-attribute` #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
518
519
520
521
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return True
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `activate()` Activate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
523
524
525
526
527
528
529
``` | ```md-code__content
def activate(self):
"""Activate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
return self.deactivate()
``` | ##### `deactivate()` Deactivate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
raise PyRevitUIError('Can not de/activate native item: {}'
.format(self))
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ### `RevitNativeRibbonGroupItem(adwnd_ribbon_item)` Bases: `GenericRevitNativeUIContainer` Revit API UI native ribbon button. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
554
555
556
557
558
559
560
561
562
``` | ```md-code__content
def __init__(self, adwnd_ribbon_item):
GenericRevitNativeUIContainer.__init__(self)
self.name = adwnd_ribbon_item.Source.Title
self._rvtapi_object = adwnd_ribbon_item
# finding children on this button group
for adwnd_ribbon_button in adwnd_ribbon_item.Items:
self._add_component(RevitNativeRibbonButton(adwnd_ribbon_button))
``` | #### Attributes ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. ##### `name = adwnd_ribbon_item.Source.Title``instance-attribute` #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
518
519
520
521
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return True
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `activate()` Activate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
523
524
525
526
527
528
529
``` | ```md-code__content
def activate(self):
"""Activate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
return self.deactivate()
``` | ##### `deactivate()` Deactivate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
raise PyRevitUIError('Can not de/activate native item: {}'
.format(self))
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ##### `button(name)` Get button item with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `name` | `str` | name of button item to find | _required_ | Returns: | Type | Description | | --- | --- | | `RevitNativeRibbonButton` | button object if found | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
564
565
566
567
568
569
570
571
572
573
``` | ```md-code__content
def button(self, name):
"""Get button item with given name.
Args:
name (str): name of button item to find
Returns:
(RevitNativeRibbonButton): button object if found
"""
return super(RevitNativeRibbonGroupItem, self)._get_component(name)
``` | ### `RevitNativeRibbonPanel(adwnd_ribbon_panel)` Bases: `GenericRevitNativeUIContainer` Revit API UI native ribbon button. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
``` | ```md-code__content
def __init__(self, adwnd_ribbon_panel):
GenericRevitNativeUIContainer.__init__(self)
self.name = adwnd_ribbon_panel.Source.Title
self._rvtapi_object = adwnd_ribbon_panel
all_adwnd_ribbon_items = []
# getting a list of existing items under this panel
# RibbonFoldPanel items are not visible. they automatically fold
# buttons into stack on revit ui resize since RibbonFoldPanel are
# not visible it does not make sense to create objects for them.
# This pre-cleaner loop, finds the RibbonFoldPanel items and
# adds the children to the main list
for adwnd_ribbon_item in adwnd_ribbon_panel.Source.Items:
if isinstance(adwnd_ribbon_item, AdWindows.RibbonFoldPanel):
try:
for sub_rvtapi_item in adwnd_ribbon_item.Items:
all_adwnd_ribbon_items.append(sub_rvtapi_item)
except Exception as append_err:
mlogger.debug('Can not get RibbonFoldPanel children: %s '
'| %s', adwnd_ribbon_item, append_err)
else:
all_adwnd_ribbon_items.append(adwnd_ribbon_item)
# processing the panel slideout for exising ribbon items
for adwnd_slideout_item \
in adwnd_ribbon_panel.Source.SlideOutPanelItemsView:
all_adwnd_ribbon_items.append(adwnd_slideout_item)
# processing the cleaned children list and
# creating pyRevit native ribbon objects
for adwnd_ribbon_item in all_adwnd_ribbon_items:
try:
if isinstance(adwnd_ribbon_item,
AdWindows.RibbonButton) \
or isinstance(adwnd_ribbon_item,
AdWindows.RibbonToggleButton):
self._add_component(
RevitNativeRibbonButton(adwnd_ribbon_item))
elif isinstance(adwnd_ribbon_item,
AdWindows.RibbonSplitButton):
self._add_component(
RevitNativeRibbonGroupItem(adwnd_ribbon_item))
except Exception as append_err:
mlogger.debug('Can not create native ribbon item: %s '
'| %s', adwnd_ribbon_item, append_err)
``` | #### Attributes ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. ##### `name = adwnd_ribbon_panel.Source.Title``instance-attribute` #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
518
519
520
521
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return True
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `activate()` Activate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
523
524
525
526
527
528
529
``` | ```md-code__content
def activate(self):
"""Activate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
return self.deactivate()
``` | ##### `deactivate()` Deactivate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
raise PyRevitUIError('Can not de/activate native item: {}'
.format(self))
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ##### `ribbon_item(item_name)` Get panel item with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of panel item to find | _required_ | Returns: | Type | Description | | --- | --- | | `object` | panel item if found, could be :obj: `RevitNativeRibbonButton`
or :obj: `RevitNativeRibbonGroupItem` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
626
627
628
629
630
631
632
633
634
635
636
637
``` | ```md-code__content
def ribbon_item(self, item_name):
"""Get panel item with given name.
Args:
item_name (str): name of panel item to find
Returns:
(object):
panel item if found, could be :obj:`RevitNativeRibbonButton`
or :obj:`RevitNativeRibbonGroupItem`
"""
return super(RevitNativeRibbonPanel, self)._get_component(item_name)
``` | ### `RevitNativeRibbonTab(adwnd_ribbon_tab)` Bases: `GenericRevitNativeUIContainer` Revit API UI native ribbon tab. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
``` | ```md-code__content
def __init__(self, adwnd_ribbon_tab):
GenericRevitNativeUIContainer.__init__(self)
self.name = adwnd_ribbon_tab.Title
self._rvtapi_object = adwnd_ribbon_tab
# getting a list of existing panels under this tab
try:
for adwnd_ribbon_panel in adwnd_ribbon_tab.Panels:
# only listing visible panels
if adwnd_ribbon_panel.IsVisible:
self._add_component(
RevitNativeRibbonPanel(adwnd_ribbon_panel)
)
except Exception as append_err:
mlogger.debug('Can not get native panels for this native tab: %s '
'| %s', adwnd_ribbon_tab, append_err)
``` | #### Attributes ##### `itemdata_mode = False``instance-attribute` ##### `visible``property``writable` Is container visible. ##### `enabled``property``writable` Is container enabled. ##### `name = adwnd_ribbon_tab.Title``instance-attribute` #### Functions ##### `process_deferred()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
282
283
284
285
286
287
288
289
290
291
292
293
294
295
``` | ```md-code__content
def process_deferred(self):
try:
if self._visible is not None:
self.visible = self._visible
except Exception as visible_err:
raise PyRevitUIError('Error setting .visible {} | {} '
.format(self, visible_err))
try:
if self._enabled is not None:
self.enabled = self._enabled
except Exception as enable_err:
raise PyRevitUIError('Error setting .enabled {} | {} '
.format(self, enable_err))
``` | ##### `get_rvtapi_object()` Return underlying Revit API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
297
298
299
300
``` | ```md-code__content
def get_rvtapi_object(self):
"""Return underlying Revit API object for this container."""
# FIXME: return type
return self._rvtapi_object
``` | ##### `set_rvtapi_object(rvtapi_obj)` Set underlying Revit API object for this container. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtapi_obj` | `obj` | Revit API container object | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
302
303
304
305
306
307
308
309
310
311
``` | ```md-code__content
def set_rvtapi_object(self, rvtapi_obj):
"""Set underlying Revit API object for this container.
Args:
rvtapi_obj (obj): Revit API container object
"""
# FIXME: rvtapi_obj type
self._rvtapi_object = rvtapi_obj
self.itemdata_mode = False
self._dirty = True
``` | ##### `get_adwindows_object()` Return underlying AdWindows API object for this container. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
313
314
315
316
317
318
319
320
321
322
323
``` | ```md-code__content
def get_adwindows_object(self):
"""Return underlying AdWindows API object for this container."""
# FIXME: return type
rvtapi_obj = self._rvtapi_object
getRibbonItemMethod = \
rvtapi_obj.GetType().GetMethod(
'getRibbonItem',
BindingFlags.NonPublic | BindingFlags.Instance
)
if getRibbonItemMethod:
return getRibbonItemMethod.Invoke(rvtapi_obj, None)
``` | ##### `get_flagged_children(state=True)` Get all children with their flag equal to given state. Flagging is a mechanism to mark certain containers. There are various reasons that container flagging might be used e.g. marking updated containers or the ones in need of an update or removal. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | flag state to filter children | `True` | Returns: | Type | Description | | --- | --- | | `list[*]` | list of filtered child objects | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
``` | ```md-code__content
def get_flagged_children(self, state=True):
"""Get all children with their flag equal to given state.
Flagging is a mechanism to mark certain containers. There are various
reasons that container flagging might be used e.g. marking updated
containers or the ones in need of an update or removal.
Args:
state (bool): flag state to filter children
Returns:
(list[*]): list of filtered child objects
"""
# FIXME: return type
flagged_cmps = []
for component in self:
flagged_cmps.extend(component.get_flagged_children(state))
if component.is_dirty() == state:
flagged_cmps.append(component)
return flagged_cmps
``` | ##### `keys()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
346
347
348
``` | ```md-code__content
def keys(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.keys())
``` | ##### `values()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
350
351
352
``` | ```md-code__content
def values(self):
# FIXME: what does this do?
list(self._sub_pyrvt_components.values())
``` | ##### `is_native()``staticmethod` Is this container generated by pyRevit or is native. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
518
519
520
521
``` | ```md-code__content
@staticmethod
def is_native():
"""Is this container generated by pyRevit or is native."""
return True
``` | ##### `is_dirty()` Is dirty flag set. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
359
360
361
362
363
364
365
366
367
368
``` | ```md-code__content
def is_dirty(self):
"""Is dirty flag set."""
if self._dirty:
return self._dirty
else:
# check if there is any dirty child
for component in self:
if component.is_dirty():
return True
return False
``` | ##### `set_dirty_flag(state=True)` Set dirty flag to given state. See .get\_flagged\_children() Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `state` | `bool` | state to set flag | `True` | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
370
371
372
373
374
375
376
377
378
``` | ```md-code__content
def set_dirty_flag(self, state=True):
"""Set dirty flag to given state.
See .get_flagged_children()
Args:
state (bool): state to set flag
"""
self._dirty = state
``` | ##### `contains(pyrvt_cmp_name)` Check if container contains a component with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrvt_cmp_name` | `str` | target component name | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
380
381
382
383
384
385
386
``` | ```md-code__content
def contains(self, pyrvt_cmp_name):
"""Check if container contains a component with given name.
Args:
pyrvt_cmp_name (str): target component name
"""
return pyrvt_cmp_name in self._sub_pyrvt_components.keys()
``` | ##### `find_child(child_name)` Find a component with given name in children. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `child_name` | `str` | target component name | _required_ | Returns: | Type | Description | | --- | --- | | `Any` | component object if found, otherwise None | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
``` | ```md-code__content
def find_child(self, child_name):
"""Find a component with given name in children.
Args:
child_name (str): target component name
Returns:
(Any): component object if found, otherwise None
"""
for sub_cmp in self._sub_pyrvt_components.values():
if child_name == sub_cmp.name:
return sub_cmp
elif hasattr(sub_cmp, 'ui_title') \
and child_name == sub_cmp.ui_title:
return sub_cmp
component = sub_cmp.find_child(child_name)
if component:
return component
return None
``` | ##### `activate()` Activate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
523
524
525
526
527
528
529
``` | ```md-code__content
def activate(self):
"""Activate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
return self.deactivate()
``` | ##### `deactivate()` Deactivate this container in ui. Under current implementation, raises PyRevitUIError exception as native Revit API UI components should not be changed. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
531
532
533
534
535
536
537
538
``` | ```md-code__content
def deactivate(self):
"""Deactivate this container in ui.
Under current implementation, raises PyRevitUIError exception as
native Revit API UI components should not be changed.
"""
raise PyRevitUIError('Can not de/activate native item: {}'
.format(self))
``` | ##### `get_updated_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
428
429
430
``` | ```md-code__content
def get_updated_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children()
``` | ##### `get_unchanged_items()` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
432
433
434
``` | ```md-code__content
def get_unchanged_items(self):
# FIXME: reduntant, this is a use case and should be on uimaker side?
return self.get_flagged_children(state=False)
``` | ##### `reorder_before(item_name, ritem_name)` Reorder and place item\_name before ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the right | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def reorder_before(self, item_name, ritem_name):
"""Reorder and place item_name before ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the right
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx - 1)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
``` | ##### `reorder_beforeall(item_name)` Reorder and place item\_name before all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
``` | ```md-code__content
def reorder_beforeall(self, item_name):
"""Reorder and place item_name before all others.
Args:
item_name (str): name of component to be moved
"""
# FIXME: verify docs description is correct
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
apiobj.Panels.Move(litem_idx, 0)
``` | ##### `reorder_after(item_name, ritem_name)` Reorder and place item\_name after ritem\_name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | | `ritem_name` | `str` | name of component that should be on the left | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
``` | ```md-code__content
def reorder_after(self, item_name, ritem_name):
"""Reorder and place item_name after ritem_name.
Args:
item_name (str): name of component to be moved
ritem_name (str): name of component that should be on the left
"""
apiobj = self.get_rvtapi_object()
litem_idx = ritem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
elif item.Source.AutomationName == ritem_name:
ritem_idx = apiobj.Panels.IndexOf(item)
if litem_idx and ritem_idx:
if litem_idx < ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx)
elif litem_idx > ritem_idx:
apiobj.Panels.Move(litem_idx, ritem_idx + 1)
``` | ##### `reorder_afterall(item_name)` Reorder and place item\_name after all others. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `item_name` | `str` | name of component to be moved | _required_ | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
``` | ```md-code__content
def reorder_afterall(self, item_name):
"""Reorder and place item_name after all others.
Args:
item_name (str): name of component to be moved
"""
apiobj = self.get_rvtapi_object()
litem_idx = None
if hasattr(apiobj, 'Panels'):
for item in apiobj.Panels:
if item.Source.AutomationName == item_name:
litem_idx = apiobj.Panels.IndexOf(item)
if litem_idx:
max_idx = len(apiobj.Panels) - 1
apiobj.Panels.Move(litem_idx, max_idx)
``` | ##### `ribbon_panel(panel_name)` Get panel with given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `panel_name` | `str` | name of panel to find | _required_ | Returns: | Type | Description | | --- | --- | | `RevitNativeRibbonPanel` | panel if found | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
660
661
662
663
664
665
666
667
668
669
``` | ```md-code__content
def ribbon_panel(self, panel_name):
"""Get panel with given name.
Args:
panel_name (str): name of panel to find
Returns:
(RevitNativeRibbonPanel): panel if found
"""
return super(RevitNativeRibbonTab, self)._get_component(panel_name)
``` | ##### `is_pyrevit_tab()``staticmethod` Is this tab generated by pyRevit. Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
671
672
673
674
``` | ```md-code__content
@staticmethod
def is_pyrevit_tab():
"""Is this tab generated by pyRevit."""
return False
``` | ## Functions ### `argb_to_brush(argb_color)` Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
``` | ```md-code__content
def argb_to_brush(argb_color):
# argb_color is formatted as #AARRGGBB
a = r = g = b = "FF"
try:
b = argb_color[-2:]
g = argb_color[-4:-2]
r = argb_color[-6:-4]
if len(argb_color) > 7:
a = argb_color[-8:-6]
return Media.SolidColorBrush(Media.Color.FromArgb(
Convert.ToInt32("0x" + a, 16),
Convert.ToInt32("0x" + r, 16),
Convert.ToInt32("0x" + g, 16),
Convert.ToInt32("0x" + b, 16)
)
)
except Exception as color_ex:
mlogger.error("Bad color format %s | %s", argb_color, color_ex)
``` | ### `load_bitmapimage(image_file)` Load given png file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `image_file` | `str` | image file path | _required_ | Returns: | Type | Description | | --- | --- | | `BitmapImage` | bitmap image object | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
``` | ```md-code__content
def load_bitmapimage(image_file):
"""Load given png file.
Args:
image_file (str): image file path
Returns:
(Imaging.BitmapImage): bitmap image object
"""
bitmap = Imaging.BitmapImage()
bitmap.BeginInit()
bitmap.UriSource = Uri(image_file)
bitmap.CacheOption = Imaging.BitmapCacheOption.OnLoad
bitmap.CreateOptions = Imaging.BitmapCreateOptions.IgnoreImageCache
bitmap.EndInit()
bitmap.Freeze()
return bitmap
``` | ### `get_current_ui(all_native=False)` Revit UI Wrapper class for interacting with current pyRevit UI. Returned class provides min required functionality for user interaction Examples: ```md-code__content current_ui = pyrevit.session.current_ui() this_script = pyrevit.session.get_this_command() current_ui.update_button_icon(this_script, new_icon) ``` Returns: | Type | Description | | --- | --- | | `_PyRevitUI` | wrapper around active ribbon gui | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
``` | ````md-code__content
def get_current_ui(all_native=False):
"""Revit UI Wrapper class for interacting with current pyRevit UI.
Returned class provides min required functionality for user interaction
Examples:
```python
current_ui = pyrevit.session.current_ui()
this_script = pyrevit.session.get_this_command()
current_ui.update_button_icon(this_script, new_icon)
```
Returns:
(_PyRevitUI): wrapper around active ribbon gui
"""
return _PyRevitUI(all_native=all_native)
```` | ### `get_uibutton(command_unique_name)` Find and return ribbon ui button with given unique id. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `command_unique_name` | `str` | unique id of pyRevit command | _required_ | Returns: | Type | Description | | --- | --- | | `_PyRevitRibbonButton` | ui button wrapper object | Source code in `pyrevitlib/pyrevit/coreutils/ribbon.py` | | | | --- | --- | | ```
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
``` | ```md-code__content
def get_uibutton(command_unique_name):
"""Find and return ribbon ui button with given unique id.
Args:
command_unique_name (str): unique id of pyRevit command
Returns:
(_PyRevitRibbonButton): ui button wrapper object
"""
# FIXME: verify return type
pyrvt_tabs = get_current_ui().get_pyrevit_tabs()
for tab in pyrvt_tabs:
button = tab.find_child(command_unique_name)
if button:
return button
return None
``` | Back to top ## BIM360 Collaboration Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/bim360/#pyrevit.revit.bim360) # bim360 BIM360-related utilities. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `COLLAB_CACHE_PATH_FORMAT = '%LOCALAPPDATA%/Autodesk/Revit/Autodesk Revit {version}/CollaborationCache'``module-attribute` ## Classes ### `CollabCacheModel(model_path)` Bases: `object` Collaboration cache for a Revit project. Source code in `pyrevitlib/pyrevit/revit/bim360.py` | | | | --- | --- | | ```
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
``` | ```md-code__content
def __init__(self, model_path):
self.model_path = model_path
self.model_dir = op.dirname(model_path)
self.model_name_ex = op.basename(model_path)
self.model_name = op.splitext(self.model_name_ex)[0]
self.central_cache_model_path = \
op.join(self.model_dir, 'CentralCache', self.model_name_ex)
self.model_backup_path = \
op.join(self.model_dir, '{}_backup'.format(self.model_name))
try:
finfo = files.get_file_info(self.model_path)
self.product = finfo.RevitProduct.Name
self.project = op.basename(finfo.CentralModelPath)
except Exception:
self.product = "?"
self.project = self.model_name_ex
``` | #### Attributes ##### `model_path = model_path``instance-attribute` ##### `model_dir = op.dirname(model_path)``instance-attribute` ##### `model_name_ex = op.basename(model_path)``instance-attribute` ##### `model_name = op.splitext(self.model_name_ex)[0]``instance-attribute` ##### `central_cache_model_path = op.join(self.model_dir, 'CentralCache', self.model_name_ex)``instance-attribute` ##### `model_backup_path = op.join(self.model_dir, '{}_backup'.format(self.model_name))``instance-attribute` ##### `product = finfo.RevitProduct.Name``instance-attribute` ##### `project = op.basename(finfo.CentralModelPath)``instance-attribute` ### `CollabCache(cache_path)` Bases: `object` Collaboration cache instance containing multiple projects. Source code in `pyrevitlib/pyrevit/revit/bim360.py` | | | | --- | --- | | ```
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
``` | ```md-code__content
def __init__(self, cache_path):
self.cache_path = cache_path
self.cache_id = op.basename(cache_path)
self.cache_models = []
for entry in os.listdir(self.cache_path):
if entry.lower().endswith('.rvt'):
self.cache_models.append(
CollabCacheModel(op.join(cache_path, entry))
)
self.cache_linked_models = []
lmodels_path = op.join(self.cache_path, 'LinkedModels')
if op.exists(lmodels_path):
for entry in os.listdir(lmodels_path):
if entry.lower().endswith('.rvt'):
self.cache_linked_models.append(
CollabCacheModel(op.join(lmodels_path, entry))
)
``` | #### Attributes ##### `cache_path = cache_path``instance-attribute` ##### `cache_id = op.basename(cache_path)``instance-attribute` ##### `cache_models = []``instance-attribute` ##### `cache_linked_models = []``instance-attribute` ## Functions ### `get_collab_caches()` Get a list of project caches stored under collaboration cache. Source code in `pyrevitlib/pyrevit/revit/bim360.py` | | | | --- | --- | | ```
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def get_collab_caches():
"""Get a list of project caches stored under collaboration cache."""
collab_root = op.normpath(op.expandvars(
COLLAB_CACHE_PATH_FORMAT.format(version=HOST_APP.version)
))
mlogger.debug('cache root: %s', collab_root)
collab_caches = []
if op.exists(collab_root):
for cache_root in os.listdir(collab_root):
cache_root_path = op.join(collab_root, cache_root)
for cache_inst in os.listdir(cache_root_path):
cache_inst_path = op.join(cache_root_path, cache_inst)
mlogger.debug('cache inst: %s', cache_inst_path)
if op.isdir(cache_inst_path):
collab_caches.append(
CollabCache(cache_inst_path)
)
return collab_caches
``` | ### `clear_model_cache(collab_cache_model)` Clear caches for given collaboration cache model. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `collab_cache_model` | `CollabCacheModel` | cache model to clear | _required_ | Source code in `pyrevitlib/pyrevit/revit/bim360.py` | | | | --- | --- | | ```
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
``` | ```md-code__content
def clear_model_cache(collab_cache_model):
"""Clear caches for given collaboration cache model.
Args:
collab_cache_model (bim360.CollabCacheModel): cache model to clear
"""
if isinstance(collab_cache_model, CollabCacheModel):
cm = collab_cache_model
mlogger.debug('Deleting %s', cm.model_path)
try:
if op.exists(cm.model_path):
os.remove(cm.model_path)
except Exception as cmdel_ex:
mlogger.error(
'Error deleting model cache @ %s | %s',
cm.model_path,
str(cmdel_ex)
)
mlogger.debug('Deleting %s', cm.model_backup_path)
try:
if op.exists(cm.model_backup_path):
coreutils.fully_remove_dir(cm.model_backup_path)
except Exception as cmbdel_ex:
mlogger.error(
'Error deleting model backup @ %s | %s',
cm.model_backup_path,
str(cmbdel_ex)
)
mlogger.debug('Deleting %s', cm.central_cache_model_path)
try:
if op.exists(cm.central_cache_model_path):
os.remove(cm.central_cache_model_path)
except Exception as ccmdel_ex:
mlogger.error(
'Error deleting central model cache @ %s | %s',
cm.central_cache_model_path,
str(ccmdel_ex)
)
``` | Back to top ## PTS PointCloud File Operations [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/pts/#pyrevit.interop.pts) # pts Read and Write PTS PointCloud Files. ## Functions ### `load(inputfile)` Read list of point tuple from PTS file. Source code in `pyrevitlib/pyrevit/interop/pts.py` | | | | --- | --- | | ```
4
5
6
7
8
9
10
11
12
13
14
15
``` | ```md-code__content
def load(inputfile):
"""Read list of point tuple from PTS file."""
points = []
with open(inputfile, 'r') as ptsfile:
# point_count = int(ptsfile.readline()) #noqa
for line in ptsfile:
data = line.split(' ')
points.append(((float(data[0]), float(data[1]), float(data[2])),
int(data[3]),
(int(data[4]), int(data[5]), int(data[6])))
)
return points
``` | ### `dump(outputfile, points)` Write list of point tuple to PTS file. Source code in `pyrevitlib/pyrevit/interop/pts.py` | | | | --- | --- | | ```
18
19
20
21
22
23
24
25
26
27
28
29
30
``` | ```md-code__content
def dump(outputfile, points):
"""Write list of point tuple to PTS file."""
point_count = len(points)
with open(outputfile, 'w') as ptsfile:
ptsfile.write(str(point_count) + '\n')
for coord, intensity, color in points:
x, y, z = coord
r, g, b = color
ptsfile.write('{:.10f} {:.10f} {:.10f} '
'{} '
'{:03} {:03} {:03}\n'.format(x, y, z,
intensity,
r, g, b))
``` | Back to top ## API Routing Server [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/routes/server/#pyrevit.routes.server) # server Handles http api routing and serving with usage similar to flask. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Classes ### `Request(path='/', method='GET', data=None, params=None)` Bases: `object` Request wrapper object. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
22
23
24
25
26
27
``` | ```md-code__content
def __init__(self, path='/', method='GET', data=None, params=None):
self.path = path
self.method = method
self.data = data
self._headers = {}
self._params = params or []
``` | #### Attributes ##### `path = path``instance-attribute` ##### `method = method``instance-attribute` ##### `data = data``instance-attribute` ##### `headers``property` Request headers dict. ##### `params``property` Request parameters. ##### `callback_url``property` Request callback url, if provided in payload. #### Functions ##### `add_header(key, value)` Add new header key:value. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
46
47
48
``` | ```md-code__content
def add_header(self, key, value):
"""Add new header key:value."""
self._headers[key] = value
``` | ### `Response(status=200, data=None, headers=None)` Bases: `object` Response wrapper object. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
53
54
55
56
``` | ```md-code__content
def __init__(self, status=200, data=None, headers=None):
self.status = status
self.data = data
self._headers = headers or {}
``` | #### Attributes ##### `status = status``instance-attribute` ##### `data = data``instance-attribute` ##### `headers``property` Response headers dict. #### Functions ##### `add_header(key, value)` Add new header key:value. Source code in `pyrevitlib/pyrevit/routes/server/base.py` | | | | --- | --- | | ```
63
64
65
``` | ```md-code__content
def add_header(self, key, value):
"""Add new header key:value."""
self._headers[key] = value
``` | ## Functions ### `init()` Initialize routes. Reset all registered routes and shutdown servers. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
32
33
34
35
36
37
``` | ```md-code__content
def init():
"""Initialize routes. Reset all registered routes and shutdown servers."""
# clear all routes
router.reset_routes()
# stop existing server
deactivate_server()
``` | ### `activate_server()` Activate routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
``` | ```md-code__content
def activate_server():
"""Activate routes server for this host instance."""
routes_server = envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
if not routes_server:
try:
rsinfo = serverinfo.register()
routes_server = \
server.RoutesServer(
host=rsinfo.server_host,
port=rsinfo.server_port
)
routes_server.start()
envvars.set_pyrevit_env_var(envvars.ROUTES_SERVER, routes_server)
return routes_server
except Exception as rs_ex:
serverinfo.unregister()
mlogger.error("Error starting Routes server | %s", str(rs_ex))
``` | ### `deactivate_server()` Deactivate the active routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
59
60
61
62
63
64
65
66
67
68
``` | ```md-code__content
def deactivate_server():
"""Deactivate the active routes server for this host instance."""
routes_server = envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
if routes_server:
try:
routes_server.stop()
envvars.set_pyrevit_env_var(envvars.ROUTES_SERVER, None)
serverinfo.unregister()
except Exception as rs_ex:
mlogger.error("Error stopping Routes server | %s", str(rs_ex))
``` | ### `get_active_server()` Get active routes server for this host instance. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
71
72
73
``` | ```md-code__content
def get_active_server():
"""Get active routes server for this host instance."""
return envvars.get_pyrevit_env_var(envvars.ROUTES_SERVER)
``` | ### `make_response(data, status=OK, headers=None)` Create Reponse object with. Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
76
77
78
79
80
81
``` | ```md-code__content
def make_response(data, status=OK, headers=None):
"""Create Reponse object with."""
res = Response(status=status, data=data)
for key, value in (headers or {}).items():
res.add_header(key, value)
return res
``` | ### `get_routes(api_name)` Get all registered routes for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
84
85
86
87
88
89
90
``` | ```md-code__content
def get_routes(api_name):
"""Get all registered routes for given API name.
Args:
api_name (str): unique name of the api
"""
return router.get_routes(api_name)
``` | ### `add_route(api_name, pattern, method, handler_func)` Add new route for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | | `pattern` | `str` | route pattern | _required_ | | `method` | `str` | method name | _required_ | | `handler_func` | `function` | route handler function | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
93
94
95
96
97
98
99
100
101
102
``` | ```md-code__content
def add_route(api_name, pattern, method, handler_func):
"""Add new route for given API name.
Args:
api_name (str): unique name of the api
pattern (str): route pattern
method (str): method name
handler_func (function): route handler function
"""
return router.add_route(api_name, pattern, method, handler_func)
``` | ### `remove_route(api_name, pattern, method)` Remove previously registered route for given API name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `api_name` | `str` | unique name of the api | _required_ | | `pattern` | `str` | route pattern | _required_ | | `method` | `str` | method name | _required_ | Source code in `pyrevitlib/pyrevit/routes/server/__init__.py` | | | | --- | --- | | ```
105
106
107
108
109
110
111
112
113
``` | ```md-code__content
def remove_route(api_name, pattern, method):
"""Remove previously registered route for given API name.
Args:
api_name (str): unique name of the api
pattern (str): route pattern
method (str): method name
"""
return router.remove_route(api_name, pattern, method)
``` | Back to top ## IxMIlia.Dxf Assembly [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/dxf/#pyrevit.interop.dxf) # dxf IxMIlia.Dxf assembly import. ## Attributes Back to top ## PyRevit Runtime Types [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/types/#pyrevit.runtime.types) # types Provide access to classes and functionalty inside base loader module. ## Attributes Back to top ## WPF Component Utilities [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/forms/utils/#pyrevit.forms.utils) # utils Utility functions to support forms module. ## Functions ### `bitmap_from_file(bitmap_file)` Create BitmapImage from a bitmap file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `bitmap_file` | `str` | path to bitmap file | _required_ | Returns: | Type | Description | | --- | --- | | `BitmapImage` | bitmap image object | Source code in `pyrevitlib/pyrevit/forms/utils.py` | | | | --- | --- | | ```
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
``` | ```md-code__content
def bitmap_from_file(bitmap_file):
"""Create BitmapImage from a bitmap file.
Args:
bitmap_file (str): path to bitmap file
Returns:
(BitmapImage): bitmap image object
"""
bitmap = Imaging.BitmapImage()
bitmap.BeginInit()
bitmap.UriSource = framework.Uri(bitmap_file)
bitmap.CacheOption = Imaging.BitmapCacheOption.OnLoad
bitmap.CreateOptions = Imaging.BitmapCreateOptions.IgnoreImageCache
bitmap.EndInit()
bitmap.Freeze()
return bitmap
``` | ### `load_component(xaml_file, comp_type)` Load WPF component from xaml file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_file` | `str` | xaml file path | _required_ | | `comp_type` | `Controls` | WPF control type | _required_ | Returns: | Type | Description | | --- | --- | | `Controls` | loaded WPF control | Source code in `pyrevitlib/pyrevit/forms/utils.py` | | | | --- | --- | | ```
26
27
28
29
30
31
32
33
34
35
36
``` | ```md-code__content
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)
``` | ### `load_ctrl_template(xaml_file)` Load System.Windows.Controls.ControlTemplate from xaml file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_file` | `str` | xaml file path | _required_ | Returns: | Type | Description | | --- | --- | | `ControlTemplate` | loaded control template | Source code in `pyrevitlib/pyrevit/forms/utils.py` | | | | --- | --- | | ```
39
40
41
42
43
44
45
46
47
48
``` | ```md-code__content
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())
``` | ### `load_itemspanel_template(xaml_file)` Load System.Windows.Controls.ItemsPanelTemplate from xaml file. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `xaml_file` | `str` | xaml file path | _required_ | Returns: | Type | Description | | --- | --- | | `ControlTemplate` | loaded items-panel template | Source code in `pyrevitlib/pyrevit/forms/utils.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
58
59
60
``` | ```md-code__content
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())
``` | Back to top ## Telemetry Records Overview [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/telemetry/record/#pyrevit.telemetry.record) # record Provides base class for telemetry records. ## Attributes ## Classes ### `CommandCustomResults` Bases: `object` Wrapper around ScriptExecutor's EXEC\_PARAMS.result\_dict. ScriptExecutor provides this results dictionary to all scripts, and scripts can add key:value pairs to the dictionary. But since the provided dictionary is a C# dictionary, this class provides a very easy to use wrapper around it. Examples: ```md-code__content CommandCustomResults().returnparam = 'some return value' ``` #### Attributes ##### `RESERVED_NAMES = ['time', 'username', 'revit', 'revitbuild', 'sessionid', 'pyrevit', 'debug', 'config', 'commandname', 'result', 'source']``class-attribute``instance-attribute` Back to top ## pyRevit Session Manager [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/loader/sessionmgr/#pyrevit.loader.sessionmgr) # sessionmgr The loader module manages the workflow of loading a new pyRevit session. Its main purpose is to orchestrate the process of finding pyRevit extensions, creating dll assemblies for them, and creating a user interface in the host application. Everything starts from `sessionmgr.load_session()` function... The only public function is `load_session()` that loads a new session. Everything else is private. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `AssembledExtension = namedtuple('AssembledExtension', ['ext', 'assm'])``module-attribute` ### `pyrevit_extcmdtype_cache = []``module-attribute` ## Classes ### `PyRevitExternalCommandType(extcmd_type, extcmd_availtype)` Bases: `object` PyRevit external command type. Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
334
335
336
337
338
339
340
341
342
``` | ```md-code__content
def __init__(self, extcmd_type, extcmd_availtype):
self._extcmd_type = extcmd_type
self._extcmd = extcmd_type()
if extcmd_availtype:
self._extcmd_availtype = extcmd_availtype
self._extcmd_avail = extcmd_availtype()
else:
self._extcmd_availtype = None
self._extcmd_avail = None
``` | #### Attributes ##### `extcmd_type``property` ##### `typename``property` ##### `extcmd_availtype``property` ##### `avail_typename``property` ##### `script``property` ##### `config_script``property` ##### `search_paths``property` ##### `arguments``property` ##### `engine_cfgs``property` ##### `helpsource``property` ##### `tooltip``property` ##### `name``property` ##### `bundle``property` ##### `extension``property` ##### `unique_id``property` #### Functions ##### `is_available(category_set, zerodoc=False)` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
406
407
408
409
410
411
412
413
``` | ```md-code__content
def is_available(self, category_set, zerodoc=False):
if self._extcmd_availtype:
return self._extcmd_avail.IsCommandAvailable(HOST_APP.uiapp,
category_set)
elif not zerodoc:
return True
return False
``` | ## Functions ### `load_session()` Handles loading/reloading of the pyRevit addin and extensions. To create a proper ui, pyRevit extensions needs to be properly parsed and a dll assembly needs to be created. This function handles these tasks through interactions with .extensions, .loader.asmmaker, and .loader.uimaker. Examples: ```md-code__content from pyrevit.loader.sessionmgr import load_session load_session() # start loading a new pyRevit session ``` Returns: | Type | Description | | --- | --- | | `str` | sesion uuid | Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
``` | ````md-code__content
def load_session():
"""Handles loading/reloading of the pyRevit addin and extensions.
To create a proper ui, pyRevit extensions needs to be properly parsed and
a dll assembly needs to be created. This function handles these tasks
through interactions with .extensions, .loader.asmmaker, and .loader.uimaker.
Examples:
```python
from pyrevit.loader.sessionmgr import load_session
load_session() # start loading a new pyRevit session
```
Returns:
(str): sesion uuid
"""
# setup runtime environment variables
sessioninfo.setup_runtime_vars()
# the loader dll addon, does not create an output window
# if an output window is not provided, create one
if EXEC_PARAMS.first_load:
output_window = _setup_output()
else:
from pyrevit import script
output_window = script.get_output()
# initialize timer to measure load time
timer = Timer()
# perform pre-load tasks
_perform_onsessionloadstart_ops()
# create a new session
_new_session()
# perform post-load tasks
_perform_onsessionloadcomplete_ops()
# log load time and thumbs-up :)
endtime = timer.get_time()
success_emoji = ':OK_hand:' if endtime < 3.00 else ':thumbs_up:'
mlogger.info('Load time: %s seconds %s', endtime, success_emoji)
# if everything went well, self destruct
try:
timeout = user_config.startuplog_timeout
if timeout > 0 and not logger.loggers_have_errors():
if EXEC_PARAMS.first_load:
# output_window is of type ScriptConsole
output_window.SelfDestructTimer(timeout)
else:
# output_window is of type PyRevitOutputWindow
output_window.self_destruct(timeout)
except Exception as imp_err:
mlogger.error('Error setting up self_destruct on output window | %s',
imp_err)
_cleanup_output()
return sessioninfo.get_session_uuid()
```` | ### `reload_pyrevit()` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
321
322
323
324
325
326
``` | ```md-code__content
def reload_pyrevit():
_perform_onsessionreload_ops()
mlogger.info('Reloading....')
session_Id = load_session()
_perform_onsessionreloadcomplete_ops()
return session_Id
``` | ### `find_all_commands(category_set=None, cache=True)` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
``` | ```md-code__content
def find_all_commands(category_set=None, cache=True):
global pyrevit_extcmdtype_cache #pylint: disable=W0603
if cache and pyrevit_extcmdtype_cache: #pylint: disable=E0601
pyrevit_extcmds = pyrevit_extcmdtype_cache
else:
pyrevit_extcmds = []
for loaded_assm_name in sessioninfo.get_loaded_pyrevit_assemblies():
loaded_assm = assmutils.find_loaded_asm(loaded_assm_name)
if loaded_assm:
all_exported_types = loaded_assm[0].GetTypes()
for pyrvt_type in all_exported_types:
tname = pyrvt_type.FullName
availtname = pyrvt_type.Name \
+ runtime.CMD_AVAIL_NAME_POSTFIX
pyrvt_availtype = None
if not tname.endswith(runtime.CMD_AVAIL_NAME_POSTFIX)\
and runtime.RUNTIME_NAMESPACE not in tname:
for exported_type in all_exported_types:
if exported_type.Name == availtname:
pyrvt_availtype = exported_type
pyrevit_extcmds.append(
PyRevitExternalCommandType(pyrvt_type,
pyrvt_availtype)
)
if cache:
pyrevit_extcmdtype_cache = pyrevit_extcmds
# now check commands in current context if requested
if category_set:
return [x for x in pyrevit_extcmds
if x.is_available(category_set=category_set,
zerodoc=HOST_APP.uidoc is None)]
else:
return pyrevit_extcmds
``` | ### `find_all_available_commands(use_current_context=True, cache=True)` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
458
459
460
461
462
463
464
``` | ```md-code__content
def find_all_available_commands(use_current_context=True, cache=True):
if use_current_context:
cset = revit.get_selection_category_set()
else:
cset = None
return find_all_commands(category_set=cset, cache=cache)
``` | ### `find_pyrevitcmd(pyrevitcmd_unique_id)` Find a pyRevit command. Searches the pyRevit-generated assemblies under current session for the command with the matching unique name (class name) and returns the command type. Notice that this returned value is a 'type' and should be instantiated before use. Examples: ```md-code__content cmd = find_pyrevitcmd('pyRevitCorepyRevitpyRevittoolsReload') command_instance = cmd() command_instance.Execute() # Provide commandData, message, elements ``` Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrevitcmd_unique_id` | `str` | Unique name for the command | _required_ | Returns: | Type | Description | | --- | --- | | `type` | Type for the command with matching unique name | Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
``` | ````md-code__content
def find_pyrevitcmd(pyrevitcmd_unique_id):
"""Find a pyRevit command.
Searches the pyRevit-generated assemblies under current session for
the command with the matching unique name (class name) and returns the
command type. Notice that this returned value is a 'type' and should be
instantiated before use.
Examples:
```python
cmd = find_pyrevitcmd('pyRevitCorepyRevitpyRevittoolsReload')
command_instance = cmd()
command_instance.Execute() # Provide commandData, message, elements
```
Args:
pyrevitcmd_unique_id (str): Unique name for the command
Returns:
(type):Type for the command with matching unique name
"""
# go through assmebles loaded under current pyRevit session
# and try to find the command
mlogger.debug('Searching for pyrevit command: %s', pyrevitcmd_unique_id)
for loaded_assm_name in sessioninfo.get_loaded_pyrevit_assemblies():
mlogger.debug('Expecting assm: %s', loaded_assm_name)
loaded_assm = assmutils.find_loaded_asm(loaded_assm_name)
if loaded_assm:
mlogger.debug('Found assm: %s', loaded_assm_name)
for pyrvt_type in loaded_assm[0].GetTypes():
mlogger.debug('Found Type: %s', pyrvt_type)
if pyrvt_type.FullName == pyrevitcmd_unique_id:
mlogger.debug('Found pyRevit command in %s',
loaded_assm_name)
return pyrvt_type
mlogger.debug('Could not find pyRevit command.')
else:
mlogger.debug('Can not find assm: %s', loaded_assm_name)
return None
```` | ### `create_tmp_commanddata()` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
509
510
511
512
513
514
515
516
517
518
``` | ```md-code__content
def create_tmp_commanddata():
tmp_cmd_data = \
framework.FormatterServices.GetUninitializedObject(
UI.ExternalCommandData
)
tmp_cmd_data.Application = HOST_APP.uiapp
# tmp_cmd_data.IsReadOnly = False
# tmp_cmd_data.View = None
# tmp_cmd_data.JournalData = None
return tmp_cmd_data
``` | ### `execute_command_cls(extcmd_type, arguments=None, config_mode=False, exec_from_ui=False)` Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
``` | ```md-code__content
def execute_command_cls(extcmd_type, arguments=None,
config_mode=False, exec_from_ui=False):
command_instance = extcmd_type()
# pass the arguments to the instance
if arguments:
command_instance.ScriptRuntimeConfigs.Arguments = \
framework.List[str](arguments)
# this is a manual execution from python code and not by user
command_instance.ExecConfigs.MimicExecFromUI = exec_from_ui
# force using the config script
command_instance.ExecConfigs.UseConfigScript = config_mode
# Execute(
# ExternalCommandData commandData,
# string message,
# ElementSet elements
# )
re = command_instance.Execute(create_tmp_commanddata(),
'',
DB.ElementSet())
command_instance = None
return re
``` | ### `execute_command(pyrevitcmd_unique_id)` Executes a pyRevit command. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `pyrevitcmd_unique_id` | `str` | Unique/Class Name of the pyRevit command | _required_ | Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
546
547
548
549
550
551
552
553
554
555
556
557
558
559
``` | ```md-code__content
def execute_command(pyrevitcmd_unique_id):
"""Executes a pyRevit command.
Args:
pyrevitcmd_unique_id (str): Unique/Class Name of the pyRevit command
"""
cmd_class = find_pyrevitcmd(pyrevitcmd_unique_id)
if not cmd_class:
mlogger.error('Can not find command with unique name: %s',
pyrevitcmd_unique_id)
return None
else:
execute_command_cls(cmd_class)
``` | ### `execute_extension_startup_script(script_path, ext_name, sys_paths=None)` Executes a script using pyRevit script executor. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `script_path` | `str` | Address of the script file | _required_ | | `ext_name` | `str` | Name of the extension | _required_ | | `sys_paths` | `list` | additional search paths | `None` | Source code in `pyrevitlib/pyrevit/loader/sessionmgr.py` | | | | --- | --- | | ```
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
``` | ```md-code__content
def execute_extension_startup_script(script_path, ext_name, sys_paths=None):
"""Executes a script using pyRevit script executor.
Args:
script_path (str): Address of the script file
ext_name (str): Name of the extension
sys_paths (list): additional search paths
"""
core_syspaths = [MAIN_LIB_DIR, MISC_LIB_DIR]
if sys_paths:
sys_paths.extend(core_syspaths)
else:
sys_paths = core_syspaths
script_data = runtime.types.ScriptData()
script_data.ScriptPath = script_path
script_data.ConfigScriptPath = None
script_data.CommandUniqueId = ''
script_data.CommandName = 'Starting {}'.format(ext_name)
script_data.CommandBundle = ''
script_data.CommandExtension = ext_name
script_data.HelpSource = ''
script_runtime_cfg = runtime.types.ScriptRuntimeConfigs()
script_runtime_cfg.CommandData = create_tmp_commanddata()
script_runtime_cfg.SelectedElements = None
script_runtime_cfg.SearchPaths = framework.List[str](sys_paths or [])
script_runtime_cfg.Arguments = framework.List[str]([])
script_runtime_cfg.EngineConfigs = \
runtime.create_ipyengine_configs(
clean=True,
full_frame=True,
persistent=True,
)
script_runtime_cfg.RefreshEngine = False
script_runtime_cfg.ConfigMode = False
script_runtime_cfg.DebugMode = False
script_runtime_cfg.ExecutedFromUI = False
runtime.types.ScriptExecutor.ExecuteScript(
script_data,
script_runtime_cfg
)
``` | Back to top ## Server Management API [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/routes/api/#pyrevit.routes.api) # api Builtin routes API. This module also provides the API object to be used by third-party api developers to define new apis ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `routes_api = routes.API('routes')``module-attribute` ## Functions ### `get_status()` Get server status. Source code in `pyrevitlib/pyrevit/routes/api.py` | | | | --- | --- | | ```
25
26
27
28
29
30
31
32
``` | ```md-code__content
@routes_api.route('/status', methods=['GET'])
def get_status():
"""Get server status."""
return {
"host": HOST_APP.pretty_name,
"username": HOST_APP.username,
"session_id": sessioninfo.get_session_uuid(),
}
``` | ### `get_sisters()` Get other servers running on the same machine. Source code in `pyrevitlib/pyrevit/routes/api.py` | | | | --- | --- | | ```
35
36
37
38
``` | ```md-code__content
@routes_api.route('/sisters', methods=['GET'])
def get_sisters():
"""Get other servers running on the same machine."""
return [x.get_cache_data() for x in serverinfo.get_registered_servers()]
``` | ### `get_sisters_by_year(version)` Get servers of specific version, running on the same machine. Source code in `pyrevitlib/pyrevit/routes/api.py` | | | | --- | --- | | ```
42
43
44
45
46
``` | ```md-code__content
@routes_api.route('/sisters/', methods=['GET'])
def get_sisters_by_year(version):
"""Get servers of specific version, running on the same machine."""
return [x.get_cache_data() for x in serverinfo.get_registered_servers()
if int(x.version) == version]
``` | Back to top ## Python Script Type Maker [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/runtime/dynamotypemaker/#pyrevit.runtime.dynamotypemaker) # dynamotypemaker Prepare and compile python script types. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ## Functions ### `create_executor_type(extension, module_builder, cmd_component)` Create the dotnet type for the executor. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `extension` | `Extension` | pyRevit extension | _required_ | | `module_builder` | `ModuleBuilder` | module builder | _required_ | | `cmd_component` | `GenericUICommand` | command | _required_ | Source code in `pyrevitlib/pyrevit/runtime/dynamotypemaker.py` | | | | --- | --- | | ```
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
``` | ```md-code__content
def create_executor_type(extension, module_builder, cmd_component):
"""Create the dotnet type for the executor.
Args:
extension (pyrevit.extensions.components.Extension): pyRevit extension
module_builder (ModuleBuilder): module builder
cmd_component (pyrevit.extensions.genericcomps.GenericUICommand):
command
"""
engine_configs = json.dumps({
exts.MDATA_ENGINE_CLEAN:
cmd_component.requires_clean_engine,
exts.MDATA_ENGINE_DYNAMO_AUTOMATE:
cmd_component.requires_mainthread_engine,
exts.MDATA_ENGINE_DYNAMO_PATH:
cmd_component.dynamo_path,
# exts.MDATA_ENGINE_DYNAMO_PATH_EXEC:
# cmd_component.dynamo_path_exec,
exts.MDATA_ENGINE_DYNAMO_PATH_CHECK_EXIST:
cmd_component.dynamo_path_check_existing,
exts.MDATA_ENGINE_DYNAMO_FORCE_MANUAL_RUN:
cmd_component.dynamo_force_manual_run,
exts.MDATA_ENGINE_DYNAMO_MODEL_NODES_INFO:
cmd_component.dynamo_model_nodes_info,
})
bundletypemaker.create_executor_type(
extension,
module_builder,
cmd_component,
eng_cfgs=engine_configs
)
``` | Back to top ## Revit Event Handlers [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/events/#pyrevit.revit.events) # events Revit events handler management. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `REGISTERED_HANDLERS = {}``module-attribute` ### `HANDLER_UNREGISTERER = FuncAsEventHandler(unregister_exec_handlers, purge=False)``module-attribute` ### `HANDLER_UNREGISTERER_EXTEVENT = UI.ExternalEvent.Create(HANDLER_UNREGISTERER)``module-attribute` ## Classes ### `FuncAsEventHandler(handler_func, purge=True)` Bases: `IExternalEventHandler` Turns a function into an event handler. Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
16
17
18
19
20
``` | ```md-code__content
def __init__(self, handler_func, purge=True):
self.name = 'FuncAsEventHandler'
self.handler_group_id = None
self.handler_func = handler_func
self.purge = purge
``` | #### Attributes ##### `name = 'FuncAsEventHandler'``instance-attribute` ##### `handler_group_id = None``instance-attribute` ##### `handler_func = handler_func``instance-attribute` ##### `purge = purge``instance-attribute` #### Functions ##### `Execute(uiapp)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
22
23
24
25
26
``` | ```md-code__content
def Execute(self, uiapp):
if self.handler_func and self.handler_group_id:
self.handler_func(self.handler_group_id)
if self.purge:
self.handler_group_id = self.handler_func = None
``` | ##### `GetName()` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
28
29
``` | ```md-code__content
def GetName(self):
return self.name
``` | ## Functions ### `create_handler(handler_func, handler_args_type)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
32
33
``` | ```md-code__content
def create_handler(handler_func, handler_args_type):
return framework.EventHandler[handler_args_type](handler_func)
``` | ### `add_handler(event_name, handler_func)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
``` | ```md-code__content
def add_handler(event_name, handler_func):
event_handler = None
if event_name == 'doc-changed':
event_handler = \
create_handler(handler_func, DB.Events.DocumentChangedEventArgs)
HOST_APP.app.DocumentChanged += event_handler
elif event_name == 'doc-closed':
event_handler = \
create_handler(handler_func, DB.Events.DocumentClosedEventArgs)
HOST_APP.app.DocumentClosed += event_handler
elif event_name == 'doc-opened':
event_handler = \
create_handler(handler_func, DB.Events.DocumentOpenedEventArgs)
HOST_APP.app.DocumentOpened += event_handler
elif event_name == 'view-activated':
event_handler = \
create_handler(handler_func, UI.Events.ViewActivatedEventArgs)
HOST_APP.uiapp.ViewActivated += event_handler
return event_handler
``` | ### `remove_handler(event_name, event_handler)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
62
63
64
65
66
67
68
69
70
71
72
73
``` | ```md-code__content
def remove_handler(event_name, event_handler):
if event_name == 'doc-changed':
HOST_APP.app.DocumentChanged -= event_handler
elif event_name == 'doc-closed':
HOST_APP.app.DocumentClosed -= event_handler
elif event_name == 'doc-opened':
HOST_APP.app.DocumentOpened -= event_handler
elif event_name == 'view-activated':
HOST_APP.uiapp.ViewActivated -= event_handler
``` | ### `register_handler(event_name, handler_func, handler_group_id)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
76
77
78
79
80
81
``` | ```md-code__content
def register_handler(event_name, handler_func, handler_group_id):
if handler_group_id not in REGISTERED_HANDLERS:
REGISTERED_HANDLERS[handler_group_id] = {}
event_handler = add_handler(event_name, handler_func)
if event_handler:
REGISTERED_HANDLERS[handler_group_id][event_name] = event_handler
``` | ### `unregister_handler(event_name, handler_func, handler_group_id)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
84
85
86
87
88
``` | ```md-code__content
def unregister_handler(event_name, handler_func, handler_group_id):
if handler_group_id in REGISTERED_HANDLERS \
and event_name in REGISTERED_HANDLERS[handler_group_id]:
event_handler = REGISTERED_HANDLERS[handler_group_id].pop(event_name)
remove_handler(event_name, event_handler)
``` | ### `unregister_exec_handlers(handler_group_id)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
91
92
93
94
95
``` | ```md-code__content
def unregister_exec_handlers(handler_group_id):
if handler_group_id in REGISTERED_HANDLERS:
for event_name, handler_func in \
REGISTERED_HANDLERS[handler_group_id].items():
unregister_handler(event_name, handler_func, handler_group_id)
``` | ### `delayed_unregister_exec_handlers(handler_group_id)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
98
99
100
``` | ```md-code__content
def delayed_unregister_exec_handlers(handler_group_id):
HANDLER_UNREGISTERER.handler_group_id = handler_group_id
HANDLER_UNREGISTERER_EXTEVENT.Raise()
``` | ### `handle(*args)` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
110
111
112
113
114
115
116
117
``` | ```md-code__content
def handle(*args): #pylint: disable=no-method-argument
def decorator(function):
def wrapper(*args, **kwargs):
return function(*args, **kwargs)
for event_name in args:
register_handler(event_name, wrapper, EXEC_PARAMS.exec_id)
return wrapper
return decorator
``` | ### `stop_events()` Source code in `pyrevitlib/pyrevit/revit/events.py` | | | | --- | --- | | ```
120
121
122
123
124
125
126
``` | ```md-code__content
def stop_events():
if EXEC_PARAMS.exec_id in REGISTERED_HANDLERS:
if HOST_APP.has_api_context:
unregister_exec_handlers(EXEC_PARAMS.exec_id)
else:
# request underegister from external event
delayed_unregister_exec_handlers(EXEC_PARAMS.exec_id)
``` | Back to top ## pyRevit Extensions Parser [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/extensions/parser/#pyrevit.extensions.parser) # parser Base module ofr parsing extensions. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ## Functions ### `parse_comp_dir(comp_path, comp_class)` Source code in `pyrevitlib/pyrevit/extensions/parser.py` | | | | --- | --- | | ```
100
101
102
103
104
105
``` | ```md-code__content
def parse_comp_dir(comp_path, comp_class):
return _create_subcomponents(
comp_path,
_get_subcomponents_classes([comp_class]),
create_from_search_dir=True
)
``` | ### `get_parsed_extension(extension)` Creates and adds the extensions components to the package. Each package object is the root to a tree of components that exists under that package. (e.g. tabs, buttons, ...) sub components of package can be accessed by iterating the \_get\_component. See \_basecomponents for types. Source code in `pyrevitlib/pyrevit/extensions/parser.py` | | | | --- | --- | | ```
108
109
110
111
112
113
114
115
116
117
``` | ```md-code__content
def get_parsed_extension(extension):
"""Creates and adds the extensions components to the package.
Each package object is the root to a tree of components that exists
under that package. (e.g. tabs, buttons, ...) sub components of package
can be accessed by iterating the _get_component.
See _basecomponents for types.
"""
_parse_for_components(extension)
return extension
``` | ### `parse_dir_for_ext_type(root_dir, parent_cmp_type)` Return the objects of type parent\_cmp\_type of the extensions in root\_dir. The package objects won't be parsed at this level. This is useful for collecting basic info on an extension type for cache cheching or updating extensions using their directory paths. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `root_dir` | `str` | directory to parse | _required_ | | `parent_cmp_type` | `type` | type of objects to return | _required_ | Source code in `pyrevitlib/pyrevit/extensions/parser.py` | | | | --- | --- | | ```
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
``` | ```md-code__content
def parse_dir_for_ext_type(root_dir, parent_cmp_type):
"""Return the objects of type parent_cmp_type of the extensions in root_dir.
The package objects won't be parsed at this level.
This is useful for collecting basic info on an extension type
for cache cheching or updating extensions using their directory paths.
Args:
root_dir (str): directory to parse
parent_cmp_type (type): type of objects to return
"""
# making sure the provided directory exists.
# This is mainly for the user defined package directories
if not op.exists(root_dir):
mlogger.debug('Extension search directory does not exist: %s', root_dir)
return []
# try creating extensions in given directory
ext_data_list = []
mlogger.debug('Parsing directory for extensions of type: %s',
parent_cmp_type)
for ext_data in _create_subcomponents(root_dir, [parent_cmp_type]):
mlogger.debug('Extension directory found: %s', ext_data)
ext_data_list.append(ext_data)
return ext_data_list
``` | Back to top ## STL File Handling [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/stl/#pyrevit.interop.stl) # stl Read and Write STL Binary and ASCII Files. Back to top ## IFC.Net Assembly Import [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/ifc/#pyrevit.interop.ifc) # ifc IFC.Net assembly import. ## Attributes Back to top ## Rhinoceros Interop [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/interop/rhino/#pyrevit.interop.rhino) # rhino Rhinoceros interop. ## Attributes Back to top ## Markdown Post-Processors [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/coreutils/markdown/postprocessors/#pyrevit.coreutils.markdown.postprocessors) # postprocessors POST-PROCESSORS. Markdown also allows post-processors, which are similar to preprocessors in that they need to implement a "run" method. However, they are run after core processing. ## Classes ### `Postprocessor(markdown_instance=None)` Bases: `Processor` Postprocessors are run after the ElementTree it converted back into text. Each Postprocessor implements a "run" method that takes a pointer to a text string, modifies it as necessary and returns a text string. Postprocessors must extend markdown.Postprocessor. Source code in `pyrevitlib/pyrevit/coreutils/markdown/util.py` | | | | --- | --- | | ```
141
142
143
``` | ```md-code__content
def __init__(self, markdown_instance=None):
if markdown_instance:
self.markdown = markdown_instance
``` | #### Attributes ##### `markdown = markdown_instance``instance-attribute` #### Functions ##### `run(text)` Main postprocessor method. Subclasses of Postprocessor should implement a `run` method, which takes the html document as a single text string and returns a (possibly modified) string. Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
37
38
39
40
41
42
43
44
``` | ```md-code__content
def run(self, text):
"""Main postprocessor method.
Subclasses of Postprocessor should implement a `run` method, which
takes the html document as a single text string and returns a
(possibly modified) string.
"""
pass # pragma: no cover
``` | ### `RawHtmlPostprocessor(markdown_instance=None)` Bases: `Postprocessor` Restore raw html to the document. Source code in `pyrevitlib/pyrevit/coreutils/markdown/util.py` | | | | --- | --- | | ```
141
142
143
``` | ```md-code__content
def __init__(self, markdown_instance=None):
if markdown_instance:
self.markdown = markdown_instance
``` | #### Attributes ##### `markdown = markdown_instance``instance-attribute` #### Functions ##### `run(text)` Iterate over html stash and restore "safe" html. Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
``` | ```md-code__content
def run(self, text):
"""Iterate over html stash and restore "safe" html."""
replacements = OrderedDict()
for i in range(self.markdown.htmlStash.html_counter):
html, safe = self.markdown.htmlStash.rawHtmlBlocks[i]
if self.markdown.safeMode and not safe:
if unicode(self.markdown.safeMode).lower() == 'escape':
html = self.escape(html)
elif unicode(self.markdown.safeMode).lower() == 'remove':
html = ''
else:
html = self.markdown.html_replacement_text
if (self.isblocklevel(html) and
(safe or not self.markdown.safeMode)):
replacements["

%s

" %
(self.markdown.htmlStash.get_placeholder(i))] = \
html + "\n"
replacements[self.markdown.htmlStash.get_placeholder(i)] = html
if replacements:
pattern = re.compile("|".join(re.escape(k) for k in replacements))
text = pattern.sub(lambda m: replacements[m.group(0)], text)
return text
``` | ##### `escape(html)` Basic html escaping. Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
75
76
77
78
79
80
``` | ```md-code__content
def escape(self, html):
"""Basic html escaping."""
html = html.replace('&', '&')
html = html.replace('<', '<')
html = html.replace('>', '>')
return html.replace('"', '"')
``` | ##### `isblocklevel(html)` Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
82
83
84
85
86
87
88
89
``` | ```md-code__content
def isblocklevel(self, html):
m = re.match(r'^\<\/?([^ >]+)', html)
if m:
if m.group(1)[0] in ('!', '?', '@', '%'):
# Comment, php etc...
return True
return util.isBlockLevel(m.group(1))
return False
``` | ### `AndSubstitutePostprocessor(markdown_instance=None)` Bases: `Postprocessor` Restore valid entities. Source code in `pyrevitlib/pyrevit/coreutils/markdown/util.py` | | | | --- | --- | | ```
141
142
143
``` | ```md-code__content
def __init__(self, markdown_instance=None):
if markdown_instance:
self.markdown = markdown_instance
``` | #### Attributes ##### `markdown = markdown_instance``instance-attribute` #### Functions ##### `run(text)` Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
95
96
97
``` | ```md-code__content
def run(self, text):
text = text.replace(util.AMP_SUBSTITUTE, "&")
return text
``` | ### `UnescapePostprocessor(markdown_instance=None)` Bases: `Postprocessor` Restore escaped chars. Source code in `pyrevitlib/pyrevit/coreutils/markdown/util.py` | | | | --- | --- | | ```
141
142
143
``` | ```md-code__content
def __init__(self, markdown_instance=None):
if markdown_instance:
self.markdown = markdown_instance
``` | #### Attributes ##### `markdown = markdown_instance``instance-attribute` ##### `RE = re.compile('%s(\\d+)%s' % (util.STX, util.ETX))``class-attribute``instance-attribute` #### Functions ##### `unescape(m)` Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
105
106
``` | ```md-code__content
def unescape(self, m):
return util.int2str(int(m.group(1)))
``` | ##### `run(text)` Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
108
109
``` | ```md-code__content
def run(self, text):
return self.RE.sub(self.unescape, text)
``` | ## Functions ### `build_postprocessors(md_instance, **kwargs)` Build the default postprocessors for Markdown. Source code in `pyrevitlib/pyrevit/coreutils/markdown/postprocessors.py` | | | | --- | --- | | ```
18
19
20
21
22
23
24
``` | ```md-code__content
def build_postprocessors(md_instance, **kwargs):
"""Build the default postprocessors for Markdown."""
postprocessors = odict.OrderedDict()
postprocessors["raw_html"] = RawHtmlPostprocessor(md_instance)
postprocessors["amp_substitute"] = AndSubstitutePostprocessor()
postprocessors["unescape"] = UnescapePostprocessor()
return postprocessors
``` | Back to top ## Server Error Exceptions [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/routes/server/exceptions/#pyrevit.routes.server.exceptions) # exceptions Route custom exceptions. ## Attributes ## Classes ### `ServerException(message, exception_type, exception_traceback)` Bases: `Exception` Server error. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
8
9
10
11
12
13
14
15
``` | ```md-code__content
def __init__(self, message, exception_type, exception_traceback):
message = "Server error (%s): %s\n%s\n" % (
exception_type.__name__ if exception_type else "",
message,
exception_traceback
)
super(ServerException, self).__init__(message)
self.status = 500 # https://httpstatuses.com/500
``` | #### Attributes ##### `status = 500``instance-attribute` ### `APINotDefinedException(api_name)` Bases: `Exception` API is not defined exception. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
20
21
22
23
``` | ```md-code__content
def __init__(self, api_name):
message = "API is not defined: \"%s\"" % api_name
super(APINotDefinedException, self).__init__(message)
self.status = 404 # https://httpstatuses.com/404
``` | #### Attributes ##### `status = 404``instance-attribute` ### `RouteHandlerNotDefinedException(api_name, route, method)` Bases: `Exception` Route does not exits exception. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
28
29
30
31
32
``` | ```md-code__content
def __init__(self, api_name, route, method):
message = \
"Route does not exits: \"%s %s%s\"" % (method, api_name, route)
super(RouteHandlerNotDefinedException, self).__init__(message)
self.status = 404 # https://httpstatuses.com/404
``` | #### Attributes ##### `status = 404``instance-attribute` ### `RouteHandlerDeniedException(request)` Bases: `Exception` Route handler was denied by host. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
37
38
39
40
41
``` | ```md-code__content
def __init__(self, request):
message = "Route handler was denied by host: \"%s\"" % request.route
super(RouteHandlerDeniedException, self).__init__(message)
self.status = 406 # https://httpstatuses.com/406
self.source = HOST_APP.pretty_name
``` | #### Attributes ##### `status = 406``instance-attribute` ##### `source = HOST_APP.pretty_name``instance-attribute` ### `RouteHandlerTimedOutException(request)` Bases: `Exception` Route handler was timed out by host. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
46
47
48
49
50
``` | ```md-code__content
def __init__(self, request):
message = "Route handler was timed out by host: \"%s\"" % request.route
super(RouteHandlerTimedOutException, self).__init__(message)
self.status = 408 # https://httpstatuses.com/408
self.source = HOST_APP.pretty_name
``` | #### Attributes ##### `status = 408``instance-attribute` ##### `source = HOST_APP.pretty_name``instance-attribute` ### `RouteHandlerIsNotCallableException(hndlr_name)` Bases: `Exception` Route handler is not callable. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
55
56
57
58
59
``` | ```md-code__content
def __init__(self, hndlr_name):
message = "Route handler is not callable: \"%s\"" % hndlr_name
super(RouteHandlerIsNotCallableException, self).__init__(message)
self.status = 405 # https://httpstatuses.com/405
self.source = HOST_APP.pretty_name
``` | #### Attributes ##### `status = 405``instance-attribute` ##### `source = HOST_APP.pretty_name``instance-attribute` ### `RouteHandlerExecException(message)` Bases: `Exception` Route handler exception. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
64
65
66
67
68
``` | ```md-code__content
def __init__(self, message):
message = "Route exception in Execute: %s" % message
super(RouteHandlerExecException, self).__init__(message)
self.status = 408 # https://httpstatuses.com/408
self.source = HOST_APP.pretty_name
``` | #### Attributes ##### `status = 408``instance-attribute` ##### `source = HOST_APP.pretty_name``instance-attribute` ### `RouteHandlerException(message, exception_type, exception_traceback, clsx_message, clsx_source, clsx_stacktrace, clsx_targetsite)` Bases: `Exception` Route handler exception. Source code in `pyrevitlib/pyrevit/routes/server/exceptions.py` | | | | --- | --- | | ```
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
``` | ```md-code__content
def __init__(self,
message, exception_type, exception_traceback,
clsx_message, clsx_source, clsx_stacktrace, clsx_targetsite):
message = "%s: %s\n%s\n" \
"Script Executor Traceback:\n" \
"%s: %s\n%s\n%s" % (
exception_type.__name__ if exception_type else "",
message,
exception_traceback,
clsx_source,
clsx_message,
clsx_stacktrace,
clsx_targetsite
)
super(RouteHandlerException, self).__init__(message)
self.status = 408 # https://httpstatuses.com/408
self.source = HOST_APP.pretty_name
``` | #### Attributes ##### `status = 408``instance-attribute` ##### `source = HOST_APP.pretty_name``instance-attribute` Back to top ## Revit Failure Handling [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/db/failure/#pyrevit.revit.db.failure) # failure Revit failures handler. ## Attributes ### `mlogger = get_logger(__name__)``module-attribute` ### `RESOLUTION_TYPES = [DB.FailureResolutionType.MoveElements, DB.FailureResolutionType.CreateElements, DB.FailureResolutionType.DetachElements, DB.FailureResolutionType.FixElements, DB.FailureResolutionType.UnlockConstraints, DB.FailureResolutionType.SkipElements, DB.FailureResolutionType.DeleteElements, DB.FailureResolutionType.QuitEditMode, DB.FailureResolutionType.SetValue, DB.FailureResolutionType.SaveDocument]``module-attribute` ## Classes ### `FailureSwallower(log_errors=True)` Bases: `IFailuresPreprocessor` Swallows all failures. Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
33
34
35
``` | ```md-code__content
def __init__(self, log_errors=True):
self._logerror = log_errors
self._failures_swallowed = []
``` | #### Functions ##### `get_swallowed_failures()` Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
51
52
53
54
55
56
57
58
59
60
61
62
63
``` | ```md-code__content
def get_swallowed_failures(self):
failures = set()
failure_reg = HOST_APP.app.GetFailureDefinitionRegistry()
if failure_reg:
for failure_id in self._failures_swallowed:
failure_obj = failure_reg.FindFailureDefinition(failure_id)
if failure_obj:
failures.add(failure_obj)
else:
mlogger.debug(
'can not find failure definition for: %s', failure_id
)
return failures
``` | ##### `reset()` Reset swallowed errors. Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
65
66
67
``` | ```md-code__content
def reset(self):
"""Reset swallowed errors."""
self._failures_swallowed = []
``` | ##### `preprocess_failures(failure_accessor)` Pythonic wrapper for `PreprocessFailures` interface method. Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
69
70
71
``` | ```md-code__content
def preprocess_failures(self, failure_accessor):
"""Pythonic wrapper for `PreprocessFailures` interface method."""
return self.PreprocessFailures(failure_accessor)
``` | ##### `PreprocessFailures(failuresAccessor)` Required IFailuresPreprocessor interface method. Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
``` | ```md-code__content
def PreprocessFailures(self, failuresAccessor):
"""Required IFailuresPreprocessor interface method."""
severity = failuresAccessor.GetSeverity()
# log some info
mlogger.debug('processing failure with severity: %s', severity)
if severity == coreutils.get_enum_none(DB.FailureSeverity):
mlogger.debug('clean document. returning with'
'FailureProcessingResult.Continue')
return DB.FailureProcessingResult.Continue
# log the failure messages
failures = failuresAccessor.GetFailureMessages()
mlogger.debug('processing %s failure messages.', len(failures))
# go through failures and attempt resolution
action_taken = False
get_elementid_value = get_elementid_value_func()
for failure in failures:
failure_id = failure.GetFailureDefinitionId()
failure_guid = getattr(failure_id, 'Guid', '')
failure_severity = failure.GetSeverity()
failure_desc = failure.GetDescriptionText()
failure_has_res = failure.HasResolutions()
# log failure info
mlogger.debug('processing failure msg: %s', failure_guid)
mlogger.debug('\tseverity: %s', failure_severity)
mlogger.debug('\tdescription: %s', failure_desc)
mlogger.debug('\telements: %s',
[get_elementid_value(x)
for x in failure.GetFailingElementIds()])
mlogger.debug('\thas resolutions: %s', failure_has_res)
# attempt resolution
mlogger.debug('attempt resolving failure: %s', failure_guid)
# if it's a warning and does not have any resolution
# delete it! it might have a popup window
if not failure_has_res \
and failure_severity == DB.FailureSeverity.Warning:
failuresAccessor.DeleteWarning(failure)
mlogger.debug(
'deleted warning with no acceptable resolution: %s',
failure_guid
)
continue
# find failure definition id
# at this point the failure_has_res is True
failure_def_accessor = get_failure_by_id(failure_id)
default_res = failure_def_accessor.GetDefaultResolutionType()
# iterate through resolution options, pick one and resolve
for res_type in RESOLUTION_TYPES:
if default_res == res_type:
mlogger.debug(
'using default failure resolution: %s', res_type)
self._set_and_resolve(failuresAccessor, failure, res_type)
action_taken = True
break
elif failure.HasResolutionOfType(res_type):
mlogger.debug('setting failure resolution to: %s', res_type)
self._set_and_resolve(failuresAccessor, failure, res_type)
# marked as action taken
action_taken = True
break
else:
mlogger.debug('invalid failure resolution: %s', res_type)
# report back
if action_taken:
mlogger.debug('resolving failures with '
'FailureProcessingResult.ProceedWithCommit')
return DB.FailureProcessingResult.ProceedWithCommit
else:
mlogger.debug('resolving failures with '
'FailureProcessingResult.Continue')
return DB.FailureProcessingResult.Continue
``` | ## Functions ### `get_failure_by_guid(failure_guid)` Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
155
156
157
158
159
``` | ```md-code__content
def get_failure_by_guid(failure_guid):
fdr = HOST_APP.app.GetFailureDefinitionRegistry()
fgid = framework.Guid(failure_guid)
fid = DB.FailureDefinitionId(fgid)
return fdr.FindFailureDefinition(fid)
``` | ### `get_failure_by_id(failure_id)` Source code in `pyrevitlib/pyrevit/revit/db/failure.py` | | | | --- | --- | | ```
162
163
164
``` | ```md-code__content
def get_failure_by_id(failure_id):
fdr = HOST_APP.app.GetFailureDefinitionRegistry()
return fdr.FindFailureDefinition(failure_id)
``` | Back to top ## Revit Query Functions [Skip to content](https://docs.pyrevitlabs.io/reference/pyrevit/revit/db/query/#pyrevit.revit.db.query) # query Helper functions to query info and elements from Revit. ## Attributes ### `mlogger = logger.get_logger(__name__)``module-attribute` ### `GRAPHICAL_VIEWTYPES = [DB.ViewType.FloorPlan, DB.ViewType.CeilingPlan, DB.ViewType.Elevation, DB.ViewType.ThreeD, DB.ViewType.Schedule, DB.ViewType.DrawingSheet, DB.ViewType.Report, DB.ViewType.DraftingView, DB.ViewType.Legend, DB.ViewType.EngineeringPlan, DB.ViewType.AreaPlan, DB.ViewType.Section, DB.ViewType.Detail, DB.ViewType.CostReport, DB.ViewType.LoadsReport, DB.ViewType.PresureLossReport, DB.ViewType.ColumnSchedule, DB.ViewType.PanelSchedule, DB.ViewType.Walkthrough, DB.ViewType.Rendering]``module-attribute` ### `DETAIL_CURVES = (DB.DetailLine, DB.DetailArc, DB.DetailEllipse, DB.DetailNurbSpline)``module-attribute` ### `MODEL_CURVES = (DB.ModelLine, DB.ModelArc, DB.ModelEllipse, DB.ModelNurbSpline)``module-attribute` ### `BUILTINCATEGORIES_VIEW = [DB.BuiltInCategory.OST_Views, DB.BuiltInCategory.OST_ReferenceViewer, DB.BuiltInCategory.OST_Viewers]``module-attribute` ### `GridPoint = namedtuple('GridPoint', ['point', 'grids'])``module-attribute` ### `SheetRefInfo = namedtuple('SheetRefInfo', ['sheet_num', 'sheet_name', 'detail_num', 'ref_viewid'])``module-attribute` ### `ElementHistory = namedtuple('ElementHistory', ['creator', 'owner', 'last_changed_by'])``module-attribute` ## Classes ## Functions ### `get_name(element, title_on_sheet=False)` Retrieves the name of a Revit element, with special handling for views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element whose name is to be retrieved. | _required_ | | `title_on_sheet` | `bool` | If True and the element is a view,
attempts to retrieve the view's title
on the sheet. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the element. For views, it may return the view's title
on the sheet if `title_on_sheet` is True and the title is available. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
``` | ```md-code__content
def get_name(element, title_on_sheet=False):
"""
Retrieves the name of a Revit element, with special handling for views.
Args:
element (DB.Element): The Revit element whose name is to be retrieved.
title_on_sheet (bool, optional): If True and the element is a view,
attempts to retrieve the view's title
on the sheet. Defaults to False.
Returns:
str: The name of the element. For views, it may return the view's title
on the sheet if `title_on_sheet` is True and the title is available.
"""
if isinstance(element, DB.View):
view_name = None
if title_on_sheet:
titleos_param = element.Parameter[DB.BuiltInParameter.VIEW_DESCRIPTION]
view_name = titleos_param.AsString()
if view_name:
return view_name
else:
if HOST_APP.is_newer_than("2019", or_equal=True):
return element.Name
else:
return element.ViewName
if PY3:
return element.Name
else:
return Element.Name.GetValue(element)
``` | ### `get_type(element)` Get element type. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | source element | _required_ | Returns: | Type | Description | | --- | --- | | `ElementType` | type object of given element | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
97
98
99
100
101
102
103
104
105
106
107
``` | ```md-code__content
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)
``` | ### `get_symbol_name(element)` Retrieves the name of the symbol associated with the given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The Revit element from which to retrieve the symbol name. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the symbol associated with the given element. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
110
111
112
113
114
115
116
117
118
119
120
``` | ```md-code__content
def get_symbol_name(element):
"""
Retrieves the name of the symbol associated with the given Revit element.
Args:
element: The Revit element from which to retrieve the symbol name.
Returns:
str: The name of the symbol associated with the given element.
"""
return get_name(element.Symbol)
``` | ### `get_family_name(element)` Retrieves the family name of a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The Revit element from which to get the family name.
It is expected to have a 'Symbol' attribute with a 'Family' property. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the family to which the element belongs. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
123
124
125
126
127
128
129
130
131
132
133
134
``` | ```md-code__content
def get_family_name(element):
"""
Retrieves the family name of a given Revit element.
Args:
element: The Revit element from which to get the family name.
It is expected to have a 'Symbol' attribute with a 'Family' property.
Returns:
str: The name of the family to which the element belongs.
"""
return get_name(element.Symbol.Family)
``` | ### `get_episodeid(element)` Extract episode id from the given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The Revit element from which to extract the episode id. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The episode id extracted from the element's UniqueId. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
139
140
141
142
143
144
145
146
147
148
149
``` | ```md-code__content
def get_episodeid(element):
"""
Extract episode id from the given Revit element.
Args:
element: The Revit element from which to extract the episode id.
Returns:
str: The episode id extracted from the element's UniqueId.
"""
return str(element.UniqueId)[:36]
``` | ### `get_guid(element)` Generates a GUID for a given Revit element by performing a bitwise XOR operation on parts of the element's UniqueId. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The Revit element for which the GUID is to be generated. The element
must have a UniqueId attribute. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | A string representing the generated GUID. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
``` | ```md-code__content
def get_guid(element):
"""
Generates a GUID for a given Revit element by performing a bitwise XOR operation
on parts of the element's UniqueId.
Args:
element: The Revit element for which the GUID is to be generated. The element
must have a UniqueId attribute.
Returns:
str: A string representing the generated GUID.
"""
uid = str(element.UniqueId)
last_32_bits = int(uid[28:36], 16)
element_id = int(uid[37:], 16)
xor = last_32_bits ^ element_id
return uid[:28] + "{0:x}".format(xor)
``` | ### `get_param(element, param_name, default=None)` Retrieves a parameter from a Revit element by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element from which to retrieve the parameter. | _required_ | | `param_name` | `str` | The name of the parameter to retrieve. | _required_ | | `default` | | The value to return if the parameter is not found or an error occurs. Defaults to None. | `None` | Returns: | Type | Description | | --- | --- | | | The parameter if found, otherwise the default value. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
``` | ```md-code__content
def get_param(element, param_name, default=None):
"""
Retrieves a parameter from a Revit element by its name.
Args:
element (DB.Element): The Revit element from which to retrieve the parameter.
param_name (str): The name of the parameter to retrieve.
default: The value to return if the parameter is not found or an error occurs. Defaults to None.
Returns:
The parameter if found, otherwise the default value.
"""
if isinstance(element, DB.Element):
try:
return element.LookupParameter(param_name)
except Exception:
return default
``` | ### `get_mark(element)` Retrieves the 'Mark' parameter value from a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The Revit element from which to retrieve the 'Mark' parameter. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The value of the 'Mark' parameter as a string. | Returns an empty string if the parameter is not found. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
190
191
192
193
194
195
196
197
198
199
200
201
202
``` | ```md-code__content
def get_mark(element):
"""
Retrieves the 'Mark' parameter value from a given Revit element.
Args:
element: The Revit element from which to retrieve the 'Mark' parameter.
Returns:
str: The value of the 'Mark' parameter as a string.
Returns an empty string if the parameter is not found.
"""
mparam = element.Parameter[DB.BuiltInParameter.ALL_MODEL_MARK]
return mparam.AsString() if mparam else ""
``` | ### `get_location(element)` Get element location point. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | source element | _required_ | Returns: | Type | Description | | --- | --- | | `XYZ` | X, Y, Z of location point element | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
205
206
207
208
209
210
211
212
213
214
215
216
217
``` | ```md-code__content
def get_location(element):
"""Get element location point.
Args:
element (DB.Element): source element
Returns:
(DB.XYZ): X, Y, Z of location point element
"""
locp = element.Location.Point
return (locp.X, locp.Y, locp.Z)
``` | ### `get_biparam_stringequals_filter(bip_paramvalue_dict)` Creates a Revit ElementParameterFilter based on a dictionary of built-in parameter (BIP) values and their corresponding filter values. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `bip_paramvalue_dict` | `dict` | A dictionary where keys are built-in parameter (BIP)
identifiers and values are the corresponding filter values. | _required_ | Returns: | Type | Description | | --- | --- | | | DB.ElementParameterFilter: A filter that can be used to filter Revit elements based
on the specified BIP values. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If no filters could be created from the provided dictionary. | Notes - The function handles different Revit API versions by checking if the host application is newer than the 2022 version. - For Revit versions newer than 2022, the `FilterStringRule` does not require the `caseSensitive` parameter. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
``` | ```md-code__content
def get_biparam_stringequals_filter(bip_paramvalue_dict):
"""
Creates a Revit ElementParameterFilter based on a dictionary of built-in parameter (BIP)
values and their corresponding filter values.
Args:
bip_paramvalue_dict (dict): A dictionary where keys are built-in parameter (BIP)
identifiers and values are the corresponding filter values.
Returns:
DB.ElementParameterFilter: A filter that can be used to filter Revit elements based
on the specified BIP values.
Raises:
PyRevitException: If no filters could be created from the provided dictionary.
Notes:
- The function handles different Revit API versions by checking if the host application
is newer than the 2022 version.
- For Revit versions newer than 2022, the `FilterStringRule` does not require the
`caseSensitive` parameter.
"""
filters = []
for bip, fvalue in bip_paramvalue_dict.items():
bip_id = DB.ElementId(bip)
bip_valueprovider = DB.ParameterValueProvider(bip_id)
if HOST_APP.is_newer_than(2022):
bip_valuerule = DB.FilterStringRule(
bip_valueprovider, DB.FilterStringEquals(), fvalue
)
else:
bip_valuerule = DB.FilterStringRule(
bip_valueprovider, DB.FilterStringEquals(), fvalue, True
)
filters.append(bip_valuerule)
if filters:
return DB.ElementParameterFilter(framework.List[DB.FilterRule](filters))
else:
raise PyRevitException("Error creating filters.")
``` | ### `get_all_elements(doc=None)` Retrieves all elements from the given Revit document. This function uses a FilteredElementCollector to collect all elements in the provided document, including both element types and instances. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to collect elements from.
If not provided, the default document (DOCS.doc) is used. | `None` | Returns: | Type | Description | | --- | --- | | | List\[Element\]: A list of all elements in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
``` | ```md-code__content
def get_all_elements(doc=None):
"""
Retrieves all elements from the given Revit document.
This function uses a FilteredElementCollector to collect all elements
in the provided document, including both element types and instances.
Args:
doc (Document, optional): The Revit document to collect elements from.
If not provided, the default document (DOCS.doc) is used.
Returns:
List[Element]: A list of all elements in the document.
"""
return (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(
DB.LogicalOrFilter(
DB.ElementIsElementTypeFilter(False),
DB.ElementIsElementTypeFilter(True),
)
)
.ToElements()
)
``` | ### `get_all_elements_in_view(view)` Retrieves all elements in the specified Revit view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view from which to collect elements. | _required_ | Returns: | Type | Description | | --- | --- | | | list\[Autodesk.Revit.DB.Element\]: A list of elements present in the specified view. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
``` | ```md-code__content
def get_all_elements_in_view(view):
"""
Retrieves all elements in the specified Revit view.
Args:
view (Autodesk.Revit.DB.View): The Revit view from which to collect elements.
Returns:
list[Autodesk.Revit.DB.Element]: A list of elements present in the specified view.
"""
return (
DB.FilteredElementCollector(view.Document, view.Id)
.WhereElementIsNotElementType()
.ToElements()
)
``` | ### `get_param_value(targetparam)` Retrieves the value of a given Revit parameter. Parameters: targetparam (DB.Parameter or DB.GlobalParameter): The parameter whose value is to be retrieved. value (varies): The value of the parameter. The type of the returned value depends on the storage type of the parameter: \- Double: Returns a float. \- Integer: Returns an int. \- String: Returns a str. \- ElementId: Returns an ElementId. If the parameter is a GlobalParameter, returns the value directly from the GlobalParameter. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
``` | ```md-code__content
def get_param_value(targetparam):
"""
Retrieves the value of a given Revit parameter.
Parameters:
targetparam (DB.Parameter or DB.GlobalParameter): The parameter whose value is to be retrieved.
Returns:
value (varies): The value of the parameter. The type of the returned value depends on the storage type of the parameter:
- Double:
Returns a float.
- Integer:
Returns an int.
- String:
Returns a str.
- ElementId:
Returns an ElementId.
If the parameter is a GlobalParameter, returns the value directly from the GlobalParameter.
"""
value = None
if isinstance(targetparam, DB.Parameter):
if targetparam.StorageType == DB.StorageType.Double:
value = targetparam.AsDouble()
elif targetparam.StorageType == DB.StorageType.Integer:
value = targetparam.AsInteger()
elif targetparam.StorageType == DB.StorageType.String:
value = targetparam.AsString()
elif targetparam.StorageType == DB.StorageType.ElementId:
value = targetparam.AsElementId()
elif isinstance(targetparam, DB.GlobalParameter):
return targetparam.GetValue().Value
return value
``` | ### `get_value_range(param_name, doc=None)` Retrieves a set of unique values for a specified parameter from all elements in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the parameter to retrieve values for. | _required_ | | `doc` | `Document` | The Revit document to search within. If None, the current document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `set` | | A set of unique values for the specified parameter. The values can be of any type, but are typically strings. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
``` | ```md-code__content
def get_value_range(param_name, doc=None):
"""
Retrieves a set of unique values for a specified parameter from all elements in the given Revit document.
Args:
param_name (str): The name of the parameter to retrieve values for.
doc (Document, optional): The Revit document to search within. If None, the current document is used.
Returns:
set: A set of unique values for the specified parameter. The values can be of any type, but are typically strings.
"""
values = set()
for element in get_all_elements(doc):
targetparam = element.LookupParameter(param_name)
if targetparam:
value = get_param_value(targetparam)
if value is not None and safe_strtype(value).lower() != "none":
if isinstance(value, str) and not value.isspace():
values.add(value)
else:
values.add(value)
return values
``` | ### `get_elements_by_parameter(param_name, param_value, doc=None, partial=False)` Retrieves elements from the Revit document that match a given parameter name and value. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the parameter to search for. | _required_ | | `param_value` | `str or other` | The value of the parameter to match. | _required_ | | `doc` | `Document` | The Revit document to search in. If None, the current document is used. | `None` | | `partial` | `bool` | If True, performs a partial match on string parameter values. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements that match the specified parameter name and value. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
``` | ```md-code__content
def get_elements_by_parameter(param_name, param_value, doc=None, partial=False):
"""
Retrieves elements from the Revit document that match a given parameter name and value.
Args:
param_name (str): The name of the parameter to search for.
param_value (str or other): The value of the parameter to match.
doc (Document, optional): The Revit document to search in. If None, the current document is used.
partial (bool, optional): If True, performs a partial match on string parameter values. Defaults to False.
Returns:
list: A list of elements that match the specified parameter name and value.
"""
found_els = []
for element in get_all_elements(doc):
targetparam = element.LookupParameter(param_name)
if targetparam:
value = get_param_value(targetparam)
if (
partial
and value is not None
and isinstance(value, str)
and param_value in value
):
found_els.append(element)
elif param_value == value:
found_els.append(element)
return found_els
``` | ### `get_elements_by_param_value(param_name, param_value, inverse=False, doc=None)` Retrieves elements from the Revit document based on a parameter name and value. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the parameter to filter by. | _required_ | | `param_value` | `str` | The value of the parameter to filter by. | _required_ | | `inverse` | `bool` | If True, inverts the filter to exclude elements with the specified parameter value. Defaults to False. | `False` | | `doc` | `Document` | The Revit document to search in. If None, uses the default document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements that match the parameter name and value. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
``` | ```md-code__content
def get_elements_by_param_value(param_name, param_value, inverse=False, doc=None):
"""
Retrieves elements from the Revit document based on a parameter name and value.
Args:
param_name (str): The name of the parameter to filter by.
param_value (str): The value of the parameter to filter by.
inverse (bool, optional): If True, inverts the filter to exclude elements with the specified parameter value. Defaults to False.
doc (Document, optional): The Revit document to search in. If None, uses the default document.
Returns:
list: A list of elements that match the parameter name and value.
"""
doc = doc or DOCS.doc
param_id = get_project_parameter_id(param_name, doc)
if param_id:
pvprov = DB.ParameterValueProvider(param_id)
pfilter = DB.FilterStringEquals()
if HOST_APP.is_newer_than(2022):
vrule = DB.FilterStringRule(pvprov, pfilter, param_value)
else:
vrule = DB.FilterStringRule(pvprov, pfilter, param_value, True)
if inverse:
vrule = DB.FilterInverseRule(vrule)
param_filter = DB.ElementParameterFilter(vrule)
return DB.FilteredElementCollector(doc).WherePasses(param_filter).ToElements()
else:
return []
``` | ### `get_elements_by_categories(element_bicats, elements=None, doc=None)` Retrieves elements from a Revit document based on specified categories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_bicats` | `list` | A list of built-in categories to filter elements by. | _required_ | | `elements` | `list` | A list of elements to filter. If provided, the function will filter these elements. | `None` | | `doc` | `Document` | The Revit document to collect elements from. If not provided, the active document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements that belong to the specified categories. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
``` | ```md-code__content
def get_elements_by_categories(element_bicats, elements=None, doc=None):
"""
Retrieves elements from a Revit document based on specified categories.
Args:
element_bicats (list): A list of built-in categories to filter elements by.
elements (list, optional): A list of elements to filter. If provided, the function will filter these elements.
doc (DB.Document, optional): The Revit document to collect elements from. If not provided, the active document is used.
Returns:
list: A list of elements that belong to the specified categories.
"""
if elements:
return [
x
for x in elements
if get_builtincategory(x.Category.Name) in element_bicats
]
cat_filters = [DB.ElementCategoryFilter(x) for x in element_bicats if x]
elcats_filter = DB.LogicalOrFilter(framework.List[DB.ElementFilter](cat_filters))
return (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(elcats_filter)
.WhereElementIsNotElementType()
.ToElements()
)
``` | ### `get_elements_by_class(element_class, elements=None, doc=None, view_id=None)` Retrieves elements of a specified class from a Revit document or a given list of elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element_class` | `type` | The class type of the elements to retrieve. | _required_ | | `elements` | `list` | A list of elements to filter by the specified class. Defaults to None. | `None` | | `doc` | `Document` | The Revit document to search within. Defaults to None. | `None` | | `view_id` | `ElementId` | The ID of the view to restrict the search to. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements of the specified class. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
``` | ```md-code__content
def get_elements_by_class(element_class, elements=None, doc=None, view_id=None):
"""
Retrieves elements of a specified class from a Revit document or a given list of elements.
Args:
element_class (type): The class type of the elements to retrieve.
elements (list, optional): A list of elements to filter by the specified class. Defaults to None.
doc (DB.Document, optional): The Revit document to search within. Defaults to None.
view_id (DB.ElementId, optional): The ID of the view to restrict the search to. Defaults to None.
Returns:
list: A list of elements of the specified class.
"""
if elements:
return [x for x in elements if isinstance(x, element_class)]
if view_id:
return (
DB.FilteredElementCollector(doc or DOCS.doc, view_id)
.OfClass(element_class)
.WhereElementIsNotElementType()
.ToElements()
)
else:
return (
DB.FilteredElementCollector(doc or DOCS.doc)
.OfClass(element_class)
.WhereElementIsNotElementType()
.ToElements()
)
``` | ### `get_types_by_class(type_class, types=None, doc=None)` Retrieves elements of a specified class type from a given list or from the Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `type_class` | `type` | The class type to filter elements by. | _required_ | | `types` | `list` | A list of elements to filter. If not provided, elements will be collected from the Revit document. | `None` | | `doc` | `Document` | The Revit document to collect elements from if 'types' is not provided. Defaults to the active document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements that are instances of the specified class type. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
``` | ```md-code__content
def get_types_by_class(type_class, types=None, doc=None):
"""
Retrieves elements of a specified class type from a given list or from the Revit document.
Args:
type_class (type): The class type to filter elements by.
types (list, optional): A list of elements to filter. If not provided, elements will be collected from the Revit document.
doc (Document, optional): The Revit document to collect elements from if 'types' is not provided. Defaults to the active document.
Returns:
list: A list of elements that are instances of the specified class type.
"""
if types:
return [x for x in types if isinstance(x, type_class)]
return DB.FilteredElementCollector(doc or DOCS.doc).OfClass(type_class).ToElements()
``` | ### `get_family(family_name, doc=None)` Retrieves all family elements in the Revit document that match the given family name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_name` | `str` | The name of the family to search for. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, the current document is used. | `None` | Returns: | Type | Description | | --- | --- | | | list\[DB.Element\]: A list of family elements that match the given family name. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
``` | ```md-code__content
def get_family(family_name, doc=None):
"""
Retrieves all family elements in the Revit document that match the given family name.
Args:
family_name (str): The name of the family to search for.
doc (DB.Document, optional): The Revit document to search in. If not provided, the current document is used.
Returns:
list[DB.Element]: A list of family elements that match the given family name.
"""
families = (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(
get_biparam_stringequals_filter(
{DB.BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM: family_name}
)
)
.WhereElementIsElementType()
.ToElements()
)
return families
``` | ### `get_family_symbol(family_name, symbol_name, doc=None)` Retrieves family symbols from a Revit document based on the specified family name and symbol name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_name` | `str` | The name of the family to search for. | _required_ | | `symbol_name` | `str` | The name of the symbol within the family to search for. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, the default document is used. | `None` | Returns: | Type | Description | | --- | --- | | | list\[DB.Element\]: A list of family symbols that match the specified family name and symbol name. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
``` | ```md-code__content
def get_family_symbol(family_name, symbol_name, doc=None):
"""
Retrieves family symbols from a Revit document based on the specified family name and symbol name.
Args:
family_name (str): The name of the family to search for.
symbol_name (str): The name of the symbol within the family to search for.
doc (DB.Document, optional): The Revit document to search in. If not provided, the default document is used.
Returns:
list[DB.Element]: A list of family symbols that match the specified family name and symbol name.
"""
famsyms = (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(
get_biparam_stringequals_filter(
{
DB.BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM: family_name,
DB.BuiltInParameter.SYMBOL_NAME_PARAM: symbol_name,
}
)
)
.WhereElementIsElementType()
.ToElements()
)
return famsyms
``` | ### `get_families(doc=None, only_editable=True)` Retrieves a list of families from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve families from.
If not provided, defaults to DOCS.doc. | `None` | | `only_editable` | `bool` | If True, only returns families that are editable.
Defaults to True. | `True` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of Family objects from the document. If only\_editable is True,
only includes families that are editable. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
``` | ```md-code__content
def get_families(doc=None, only_editable=True):
"""
Retrieves a list of families from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve families from.
If not provided, defaults to DOCS.doc.
only_editable (bool, optional): If True, only returns families that are editable.
Defaults to True.
Returns:
list: A list of Family objects from the document. If only_editable is True,
only includes families that are editable.
"""
doc = doc or DOCS.doc
families = [
x.Family
for x in set(
DB.FilteredElementCollector(doc).WhereElementIsElementType().ToElements()
)
if isinstance(x, (DB.FamilySymbol, DB.AnnotationSymbolType))
]
if only_editable:
return [x for x in families if x.IsEditable]
return families
``` | ### `get_noteblock_families(doc=None)` Retrieves a list of noteblock families from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of noteblock family elements in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
``` | ```md-code__content
def get_noteblock_families(doc=None):
"""
Retrieves a list of noteblock families from the given Revit document.
Args:
doc (Document, optional): The Revit document to query. If not provided,
the default document (DOCS.doc) will be used.
Returns:
list: A list of noteblock family elements in the document.
"""
doc = doc or DOCS.doc
return [
doc.GetElement(x) for x in DB.ViewSchedule.GetValidFamiliesForNoteBlock(doc)
]
``` | ### `get_elements_by_family(family_name, doc=None)` Retrieves elements from a Revit document based on the specified family name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_name` | `str` | The name of the family to filter elements by. | _required_ | | `doc` | `Document` | The Revit document to search within. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Type | Description | | --- | --- | | | list\[DB.Element\]: A list of elements that belong to the specified family. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
``` | ```md-code__content
def get_elements_by_family(family_name, doc=None):
"""
Retrieves elements from a Revit document based on the specified family name.
Args:
family_name (str): The name of the family to filter elements by.
doc (DB.Document, optional): The Revit document to search within. If not provided,
the default document (DOCS.doc) will be used.
Returns:
list[DB.Element]: A list of elements that belong to the specified family.
"""
famsyms = (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(
get_biparam_stringequals_filter(
{DB.BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM: family_name}
)
)
.WhereElementIsNotElementType()
.ToElements()
)
return famsyms
``` | ### `get_elements_by_familytype(family_name, symbol_name, doc=None)` Retrieves elements from a Revit document based on the specified family and symbol names. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_name` | `str` | The name of the family to filter elements by. | _required_ | | `symbol_name` | `str` | The name of the symbol (type) to filter elements by. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, the current document is used. | `None` | Returns: | Type | Description | | --- | --- | | | list\[DB.Element\]: A list of elements that match the specified family and symbol names. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
``` | ```md-code__content
def get_elements_by_familytype(family_name, symbol_name, doc=None):
"""
Retrieves elements from a Revit document based on the specified family and symbol names.
Args:
family_name (str): The name of the family to filter elements by.
symbol_name (str): The name of the symbol (type) to filter elements by.
doc (DB.Document, optional): The Revit document to search in. If not provided, the current document is used.
Returns:
list[DB.Element]: A list of elements that match the specified family and symbol names.
"""
syms = (
DB.FilteredElementCollector(doc or DOCS.doc)
.WherePasses(
get_biparam_stringequals_filter(
{
DB.BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM: family_name,
DB.BuiltInParameter.SYMBOL_NAME_PARAM: symbol_name,
}
)
)
.WhereElementIsNotElementType()
.ToElements()
)
return syms
``` | ### `find_workset(workset_name_or_list, doc=None, partial=True)` Finds a workset in the given Revit document by name or list of names. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `workset_name_or_list` | `str or list` | The name of the workset to find or a list of workset names. | _required_ | | `doc` | `Document` | The Revit document to search in. If None, the default document is used. | `None` | | `partial` | `bool` | If True, allows partial matching of workset names. Defaults to True. | `True` | Returns: | Name | Type | Description | | --- | --- | --- | | `Workset` | | The first matching workset found, or None if no match is found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
``` | ```md-code__content
def find_workset(workset_name_or_list, doc=None, partial=True):
"""
Finds a workset in the given Revit document by name or list of names.
Args:
workset_name_or_list (str or list): The name of the workset to find or a list of workset names.
doc (Document, optional): The Revit document to search in. If None, the default document is used.
partial (bool, optional): If True, allows partial matching of workset names. Defaults to True.
Returns:
Workset: The first matching workset found, or None if no match is found.
"""
workset_clctr = DB.FilteredWorksetCollector(doc or DOCS.doc).ToWorksets()
if isinstance(workset_name_or_list, list):
for workset in workset_clctr:
for workset_name in workset_name_or_list:
if workset_name in workset.Name:
return workset
elif isinstance(workset_name_or_list, str):
workset_name = workset_name_or_list
if partial:
for workset in workset_clctr:
if workset_name in workset.Name:
return workset
else:
for workset in workset_clctr:
if workset_name == workset.Name:
return workset
``` | ### `model_has_family(family_name, doc=None)` Checks if the Revit model contains a family with the given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_name` | `str` | The name of the family to search for. | _required_ | | `doc` | `Document` | The Revit document to search in. If None, the current document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the family is found in the model, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
677
678
679
680
681
682
683
684
685
686
687
688
689
``` | ```md-code__content
def model_has_family(family_name, doc=None):
"""
Checks if the Revit model contains a family with the given name.
Args:
family_name (str): The name of the family to search for.
doc (Document, optional): The Revit document to search in. If None, the current document is used.
Returns:
bool: True if the family is found in the model, False otherwise.
"""
collector = get_family(family_name, doc=doc)
return hasattr(collector, "Count") and collector.Count > 0
``` | ### `model_has_workset(workset_name, partial=False, doc=None)` Checks if the model has a workset with the given name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `workset_name` | `str` | The name of the workset to search for. | _required_ | | `partial` | `bool` | If True, allows partial matching of the workset name. Defaults to False. | `False` | | `doc` | `Document` | The Revit document to search within. If None, the current document is used. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the workset is found, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
692
693
694
695
696
697
698
699
700
701
702
703
704
705
``` | ```md-code__content
def model_has_workset(workset_name, partial=False, doc=None):
"""
Checks if the model has a workset with the given name.
Args:
workset_name (str): The name of the workset to search for.
partial (bool, optional): If True, allows partial matching of the workset name. Defaults to False.
doc (Document, optional): The Revit document to search within. If None, the current document is used. Defaults to None.
Returns:
bool: True if the workset is found, False otherwise.
"""
return find_workset(workset_name, partial=partial, doc=doc)
``` | ### `get_worksets_names(doc=None)` Returns a string with the names of all user worksets in a document Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `document` | `Document` | A Revit document. de | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | A string with the names of all user worksets in a document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
``` | ```md-code__content
def get_worksets_names(doc=None):
"""
Returns a string with the names of all user worksets in a document
Args:
document (Document): A Revit document. de
Returns:
str: A string with the names of all user worksets in a document.
"""
doc = doc or DOCS.doc
if not hasattr(doc, "IsWorkshared"):
return "-"
if not doc.IsWorkshared:
return "Not Workshared"
worksets_collection = (
DB.FilteredWorksetCollector(doc).OfKind(DB.WorksetKind.UserWorkset).ToWorksets()
)
return ", ".join(w.Name for w in worksets_collection)
``` | ### `get_critical_warnings_count(warnings, critical_warnings_template)` Counts the number of critical warnings from a list of warnings based on a template. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `warnings` | `list` | A list of warning objects. Each warning object should have a method
`GetFailureDefinitionId` that returns an object with a `Guid` attribute. | _required_ | | `critical_warnings_template` | `list` | A list of string representations of GUIDs that are
considered critical warnings. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `int` | | The count of critical warnings. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
``` | ```md-code__content
def get_critical_warnings_count(warnings, critical_warnings_template):
"""
Counts the number of critical warnings from a list of warnings based on a template.
Args:
warnings (list): A list of warning objects. Each warning object should have a method
`GetFailureDefinitionId` that returns an object with a `Guid` attribute.
critical_warnings_template (list): A list of string representations of GUIDs that are
considered critical warnings.
Returns:
int: The count of critical warnings.
"""
warnings_guid = [warning.GetFailureDefinitionId().Guid for warning in warnings]
return sum(
1
for warning_guid in warnings_guid
if str(warning_guid) in critical_warnings_template
)
``` | ### `get_sharedparam_definition_file()` Retrieves the shared parameters definition file from the host application. Returns: | Name | Type | Description | | --- | --- | --- | | `SharedParameterFile` | | The shared parameters file if it exists and is successfully opened. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the shared parameters file is not defined or cannot be opened. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
``` | ```md-code__content
def get_sharedparam_definition_file():
"""
Retrieves the shared parameters definition file from the host application.
Returns:
SharedParameterFile: The shared parameters file if it exists and is successfully opened.
Raises:
PyRevitException: If the shared parameters file is not defined or cannot be opened.
"""
if HOST_APP.app.SharedParametersFilename:
sparamf = HOST_APP.app.OpenSharedParameterFile()
if sparamf:
return sparamf
else:
raise PyRevitException("Failed opening Shared Parameters file.")
else:
raise PyRevitException("No Shared Parameters file defined.")
``` | ### `get_defined_sharedparams()` Retrieves all defined shared parameters from the shared parameter file. Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of DB.ExternalDefinition objects representing the shared parameters. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If there is an error accessing the shared parameter file. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
``` | ```md-code__content
def get_defined_sharedparams():
"""
Retrieves all defined shared parameters from the shared parameter file.
Returns:
list: A list of DB.ExternalDefinition objects representing the shared parameters.
Raises:
PyRevitException: If there is an error accessing the shared parameter file.
"""
pp_list = []
try:
for def_group in get_sharedparam_definition_file().Groups:
pp_list.extend([x for x in def_group.Definitions])
except PyRevitException as ex:
mlogger.debug("Error getting shared parameters. | %s", ex)
return pp_list
``` | ### `get_project_parameters(doc=None)` Retrieves the project parameters from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve the project parameters.
If not provided, defaults to `DOCS.doc`. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of ProjectParameter objects representing the project parameters in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
``` | ```md-code__content
def get_project_parameters(doc=None):
"""
Retrieves the project parameters from the given Revit document.
Args:
doc (Document, optional): The Revit document from which to retrieve the project parameters.
If not provided, defaults to `DOCS.doc`.
Returns:
list: A list of ProjectParameter objects representing the project parameters in the document.
"""
doc = doc or DOCS.doc
shared_params = {x.Name: x for x in get_defined_sharedparams()}
pp_list = []
if doc and not doc.IsFamilyDocument:
param_bindings = doc.ParameterBindings
pb_iterator = param_bindings.ForwardIterator()
pb_iterator.Reset()
while pb_iterator.MoveNext():
msp = db.ProjectParameter(
pb_iterator.Key,
param_bindings[pb_iterator.Key],
param_ext_def=shared_params.get(pb_iterator.Key.Name, None),
)
pp_list.append(msp)
return pp_list
``` | ### `get_project_parameter_id(param_name, doc=None)` Retrieves the ID of a project parameter by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the project parameter to find. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `ElementId` | | The ID of the project parameter. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the parameter with the specified name is not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
``` | ```md-code__content
def get_project_parameter_id(param_name, doc=None):
"""
Retrieves the ID of a project parameter by its name.
Args:
param_name (str): The name of the project parameter to find.
doc (Document, optional): The Revit document to search in. If not provided,
the default document (DOCS.doc) will be used.
Returns:
ElementId: The ID of the project parameter.
Raises:
PyRevitException: If the parameter with the specified name is not found.
"""
doc = doc or DOCS.doc
for project_param in get_project_parameters(doc):
if project_param.name == param_name:
return project_param.param_id
raise PyRevitException("Parameter not found: {}".format(param_name))
``` | ### `get_project_parameter(param_id_or_name, doc=None)` Retrieves a project parameter by its ID or name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_id_or_name` | `str or int` | The ID or name of the project parameter to retrieve. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, the default document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `ProjectParameter` | | The matching project parameter if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
``` | ```md-code__content
def get_project_parameter(param_id_or_name, doc=None):
"""
Retrieves a project parameter by its ID or name.
Args:
param_id_or_name (str or int): The ID or name of the project parameter to retrieve.
doc (Document, optional): The Revit document to search in. If not provided, the default document is used.
Returns:
ProjectParameter: The matching project parameter if found, otherwise None.
"""
pp_list = get_project_parameters(doc or DOCS.doc)
for msp in pp_list:
if msp == param_id_or_name:
return msp
return None
``` | ### `model_has_parameter(param_id_or_name, doc=None)` Checks if the model has a specific parameter by its ID or name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_id_or_name` | `str or int` | The parameter ID or name to check for. | _required_ | | `doc` | `Document` | The Revit document to search in. If None, the current document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the parameter exists in the model, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
861
862
863
864
865
866
867
868
869
870
871
872
``` | ```md-code__content
def model_has_parameter(param_id_or_name, doc=None):
"""
Checks if the model has a specific parameter by its ID or name.
Args:
param_id_or_name (str or int): The parameter ID or name to check for.
doc (Document, optional): The Revit document to search in. If None, the current document is used.
Returns:
bool: True if the parameter exists in the model, False otherwise.
"""
return get_project_parameter(param_id_or_name, doc=doc)
``` | ### `get_global_parameters(doc=None)` Retrieves all global parameters from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve global parameters.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of global parameter elements in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
``` | ```md-code__content
def get_global_parameters(doc=None):
"""
Retrieves all global parameters from the given Revit document.
Args:
doc (Document, optional): The Revit document from which to retrieve global parameters.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of global parameter elements in the document.
"""
doc = doc or DOCS.doc
return [
doc.GetElement(x)
for x in DB.GlobalParametersManager.GetAllGlobalParameters(doc)
]
``` | ### `get_global_parameter(param_name, doc=None)` Retrieves a global parameter by its name from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the global parameter to retrieve. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | DB.GlobalParameter: The global parameter element if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
``` | ```md-code__content
def get_global_parameter(param_name, doc=None):
"""
Retrieves a global parameter by its name from the given Revit document.
Args:
param_name (str): The name of the global parameter to retrieve.
doc (DB.Document, optional): The Revit document to search in. If not provided, defaults to DOCS.doc.
Returns:
DB.GlobalParameter: The global parameter element if found, otherwise None.
"""
doc = doc or DOCS.doc
if features.GLOBAL_PARAMS:
param_id = DB.GlobalParametersManager.FindByName(doc, param_name)
if param_id != DB.ElementId.InvalidElementId:
return doc.GetElement(param_id)
``` | ### `get_project_info(doc=None)` Retrieves the project information from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve the project information.
If not provided, the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `ProjectInfo` | | The project information of the specified or default Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
911
912
913
914
915
916
917
918
919
920
921
922
``` | ```md-code__content
def get_project_info(doc=None):
"""
Retrieves the project information from the given Revit document.
Args:
doc (Document, optional): The Revit document from which to retrieve the project information.
If not provided, the default document (DOCS.doc) will be used.
Returns:
ProjectInfo: The project information of the specified or default Revit document.
"""
return db.ProjectInfo(doc or DOCS.doc)
``` | ### `get_phases_names(doc=None)` Returns a comma-separated list of the names of the phases in a project. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `document` | `Document` | A Revit document. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | A comma-separated list of the names of the phases in a project. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
``` | ```md-code__content
def get_phases_names(doc=None):
"""
Returns a comma-separated list of the names of the phases in a project.
Args:
document (Document): A Revit document.
Returns:
str: A comma-separated list of the names of the phases in a project.
"""
if not hasattr(doc, "Phases"):
return "-"
return ", ".join(phase.Name for phase in doc.Phases)
``` | ### `get_revisions(doc=None)` Retrieves a list of revision elements from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve revisions from.
If not provided, the default document (DOCS.doc) is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of revision elements in the specified Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
``` | ```md-code__content
def get_revisions(doc=None):
"""
Retrieves a list of revision elements from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve revisions from.
If not provided, the default document (DOCS.doc) is used.
Returns:
list: A list of revision elements in the specified Revit document.
"""
return list(
DB.FilteredElementCollector(doc or DOCS.doc)
.OfCategory(DB.BuiltInCategory.OST_Revisions)
.WhereElementIsNotElementType()
)
``` | ### `get_sheet_revisions(sheet)` Retrieves the revisions associated with a given Revit sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sheet` | `ViewSheet` | The Revit sheet from which to retrieve revisions. | _required_ | Returns: | Type | Description | | --- | --- | | | list\[Autodesk.Revit.DB.Element\]: A list of revision elements associated with the sheet. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
961
962
963
964
965
966
967
968
969
970
971
972
``` | ```md-code__content
def get_sheet_revisions(sheet):
"""
Retrieves the revisions associated with a given Revit sheet.
Args:
sheet (Autodesk.Revit.DB.ViewSheet): The Revit sheet from which to retrieve revisions.
Returns:
list[Autodesk.Revit.DB.Element]: A list of revision elements associated with the sheet.
"""
doc = sheet.Document
return [doc.GetElement(x) for x in sheet.GetAdditionalRevisionIds()]
``` | ### `get_current_sheet_revision(sheet)` Retrieves the current revision of the given sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sheet` | `ViewSheet` | The sheet for which to get the current revision. | _required_ | Returns: | Type | Description | | --- | --- | | | Autodesk.Revit.DB.Element: The current revision element of the sheet. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
975
976
977
978
979
980
981
982
983
984
985
986
``` | ```md-code__content
def get_current_sheet_revision(sheet):
"""
Retrieves the current revision of the given sheet.
Args:
sheet (Autodesk.Revit.DB.ViewSheet): The sheet for which to get the current revision.
Returns:
Autodesk.Revit.DB.Element: The current revision element of the sheet.
"""
doc = sheet.Document
return doc.GetElement(sheet.GetCurrentRevision())
``` | ### `get_sheets(include_placeholders=True, include_noappear=True, doc=None)` Retrieves a list of sheets from the Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `include_placeholders` | `bool` | If True, includes placeholder sheets in the result. Defaults to True. | `True` | | `include_noappear` | `bool` | If True, includes sheets that do not appear in the project browser. Defaults to True. | `True` | | `doc` | `Document` | The Revit document to retrieve sheets from. If None, uses the current document. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of sheets from the specified Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
``` | ```md-code__content
def get_sheets(include_placeholders=True, include_noappear=True, doc=None):
"""
Retrieves a list of sheets from the Revit document.
Args:
include_placeholders (bool, optional): If True, includes placeholder sheets in the result. Defaults to True.
include_noappear (bool, optional): If True, includes sheets that do not appear in the project browser. Defaults to True.
doc (Document, optional): The Revit document to retrieve sheets from. If None, uses the current document. Defaults to None.
Returns:
list: A list of sheets from the specified Revit document.
"""
sheets = list(
DB.FilteredElementCollector(doc or DOCS.doc)
.OfCategory(DB.BuiltInCategory.OST_Sheets)
.WhereElementIsNotElementType()
)
if not include_noappear:
sheets = [
x
for x in sheets
if x.Parameter[DB.BuiltInParameter.SHEET_SCHEDULED].AsInteger() > 0
]
if not include_placeholders:
return [x for x in sheets if not x.IsPlaceholder]
return sheets
``` | ### `get_document_clean_name(doc=None)` Return the name of the given document without the file path or file extension. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve links from. If None, the default document
(DOCS.doc) is used. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the given document without the file path or file | | | | extension. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
``` | ```md-code__content
def get_document_clean_name(doc=None):
"""
Return the name of the given document without the file path or file
extension.
Args:
doc (DB.Document, optional): The Revit document to retrieve links from. If None, the default document
(DOCS.doc) is used. Defaults to None.
Returns:
str: The name of the given document without the file path or file
extension.
"""
document_name = db.ProjectInfo(doc or DOCS.doc).path
if not document_name:
return "File Not Saved"
if document_name.startswith("BIM 360://"):
path = document_name.split("://", 1)[1]
else:
path = document_name
return splitext(basename(path))[0]
``` | ### `get_links(linktype=None, doc=None)` Retrieves external file references (links) from a Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `linktype` | `ExternalFileReferenceType` | The type of external file reference to filter by.
If None, all external file references are returned. Defaults to None. | `None` | | `doc` | `Document` | The Revit document to retrieve links from. If None, the default document
(DOCS.doc) is used. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of db.ExternalRef objects representing the external file references in the document. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the document is not saved or if there is an error reading the links from the model path. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
``` | ```md-code__content
def get_links(linktype=None, doc=None):
"""
Retrieves external file references (links) from a Revit document.
Args:
linktype (DB.ExternalFileReferenceType, optional): The type of external file reference to filter by.
If None, all external file references are returned. Defaults to None.
doc (DB.Document, optional): The Revit document to retrieve links from. If None, the default document
(DOCS.doc) is used. Defaults to None.
Returns:
list: A list of db.ExternalRef objects representing the external file references in the document.
Raises:
PyRevitException: If the document is not saved or if there is an error reading the links from the model path.
"""
doc = doc or DOCS.doc
location = doc.PathName
if not location:
raise PyRevitException("PathName is empty. Model is not saved.")
links = []
model_path = DB.ModelPathUtils.ConvertUserVisiblePathToModelPath(location)
if not model_path:
raise PyRevitException("Model is not saved. Can not read links.")
try:
trans_data = DB.TransmissionData.ReadTransmissionData(model_path)
external_refs = trans_data.GetAllExternalFileReferenceIds()
for ref_id in external_refs:
ext_ref = trans_data.GetLastSavedReferenceData(ref_id)
link = doc.GetElement(ref_id)
if linktype:
if ext_ref.ExternalFileReferenceType == linktype:
links.append(db.ExternalRef(link, ext_ref))
else:
links.append(db.ExternalRef(link, ext_ref))
return links
except Exception as data_err:
raise PyRevitException(
"Error reading links from model path: {} | {}".format(model_path, data_err)
)
``` | ### `get_linked_models(doc=None, loaded_only=False)` Retrieves the linked Revit models in the given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for linked models.
If None, defaults to DOCS.doc. | `None` | | `loaded_only` | `bool` | If True, only returns the linked models that are currently loaded.
Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of linked Revit models. If loaded\_only is True, only the loaded models are returned. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
``` | ```md-code__content
def get_linked_models(doc=None, loaded_only=False):
"""
Retrieves the linked Revit models in the given document.
Args:
doc (Document, optional): The Revit document to search for linked models.
If None, defaults to DOCS.doc.
loaded_only (bool, optional): If True, only returns the linked models that are currently loaded.
Defaults to False.
Returns:
list: A list of linked Revit models. If loaded_only is True, only the loaded models are returned.
"""
doc = doc or DOCS.doc
linkedmodels = get_links(linktype=DB.ExternalFileReferenceType.RevitLink, doc=doc)
if loaded_only:
return [x for x in linkedmodels if DB.RevitLinkType.IsLoaded(doc, x.id)]
return linkedmodels
``` | ### `get_linked_model_doc(linked_model)` Retrieves the document of a linked Revit model. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `linked_model` | `Union[RevitLinkType, ExternalRef]` | The linked model, which can be either a RevitLinkType or an ExternalRef. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `Document` | | The document of the linked model if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
``` | ```md-code__content
def get_linked_model_doc(linked_model):
"""
Retrieves the document of a linked Revit model.
Args:
linked_model (Union[DB.RevitLinkType, db.ExternalRef]): The linked model, which can be either a RevitLinkType or an ExternalRef.
Returns:
Document: The document of the linked model if found, otherwise None.
"""
lmodel = None
if isinstance(linked_model, DB.RevitLinkType):
lmodel = db.ExternalRef(linked_model) # pylint: disable=E1120
elif isinstance(linked_model, db.ExternalRef):
lmodel = linked_model
if lmodel:
for open_doc in DOCS.docs:
if open_doc.Title == lmodel.name:
return open_doc
``` | ### `get_linked_model_types(doc, rvt_links_instances)` Retrieves the types of linked Revit models. Args: doc (Document): The Revit document. Defaults to None. rvt\_links\_instances (list): A list of Revit link instances. Returns: list: A list of linked model types. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
``` | ```md-code__content
def get_linked_model_types(doc, rvt_links_instances):
"""
Retrieves the types of linked Revit models.
Args:
doc (Document): The Revit document. Defaults to None.
rvt_links_instances (list): A list of Revit link instances.
Returns:
list: A list of linked model types.
"""
return [doc.GetElement(rvtlink.GetTypeId()) for rvtlink in rvt_links_instances]
``` | ### `get_linked_model_instances(doc=None)` Returns a list of all rvt\_links instances in a document Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | A Revit document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of Revit link instances. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
``` | ```md-code__content
def get_linked_model_instances(doc=None):
"""
Returns a list of all rvt_links instances in a document
Args:
doc (Document): A Revit document.
Returns:
list: A list of Revit link instances.
"""
return (
DB.FilteredElementCollector(doc or DOCS.doc)
.OfCategory(DB.BuiltInCategory.OST_RvtLinks)
.WhereElementIsNotElementType()
)
``` | ### `get_rvt_link_status(doc=None)` Retrieves the status of linked Revit models in the given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. If None, the current document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of statuses for each linked Revit model type. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
``` | ```md-code__content
def get_rvt_link_status(doc=None):
"""
Retrieves the status of linked Revit models in the given document.
Args:
doc (Document, optional): The Revit document to query. If None, the current document is used.
Returns:
list: A list of statuses for each linked Revit model type.
"""
doc = doc or DOCS.doc
rvtlinks_instances = get_linked_model_instances(doc)
rvtlinks_types = get_linked_model_types(doc, rvtlinks_instances)
return [rvtlinktype.GetLinkedFileStatus() for rvtlinktype in rvtlinks_types]
``` | ### `get_rvt_link_doc_name(rvtlink_instance)` Retrieves the name of the Revit link document from the given Revit link instance. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtlink_instance` | | The Revit link instance from which to extract the document name. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the Revit link document, without the file extension and any directory paths. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
``` | ```md-code__content
def get_rvt_link_doc_name(rvtlink_instance):
"""
Retrieves the name of the Revit link document from the given Revit link instance.
Args:
rvtlink_instance: The Revit link instance from which to extract the document name.
Returns:
str: The name of the Revit link document, without the file extension and any directory paths.
"""
return get_name(rvtlink_instance).split("\\")[0].split(".rvt")[0]
``` | ### `get_rvt_link_instance_name(rvtlink_instance=None)` Retrieves the name of a Revit link instance. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `rvtlink_instance` | | The Revit link instance object. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The name of the Revit link instance, extracted from the full name. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
``` | ```md-code__content
def get_rvt_link_instance_name(rvtlink_instance=None):
"""
Retrieves the name of a Revit link instance.
Args:
rvtlink_instance: The Revit link instance object.
Returns:
str: The name of the Revit link instance, extracted from the full name.
"""
return get_name(rvtlink_instance).split(" : ")[1]
``` | ### `find_first_legend(doc=None)` Finds the first legend view in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search in. If not provided,
it defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `View` | | The first legend view found in the document, or None if no legend view is found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
``` | ```md-code__content
def find_first_legend(doc=None):
"""
Finds the first legend view in the given Revit document.
Args:
doc (Document, optional): The Revit document to search in. If not provided,
it defaults to DOCS.doc.
Returns:
View: The first legend view found in the document, or None if no legend view is found.
"""
doc = doc or DOCS.doc
for view in DB.FilteredElementCollector(doc).OfClass(DB.View):
if view.ViewType == DB.ViewType.Legend and not view.IsTemplate:
return view
return None
``` | ### `compare_revisions(src_rev, dest_rev, case_sensitive=False)` Compare two revision objects based on specific attributes. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `src_rev` | `object` | The source revision object to compare. | _required_ | | `dest_rev` | `object` | The destination revision object to compare. | _required_ | | `case_sensitive` | `bool` | Flag to indicate if the comparison should be case sensitive. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if all specified attributes match between the two revisions, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
``` | ```md-code__content
def compare_revisions(src_rev, dest_rev, case_sensitive=False):
"""
Compare two revision objects based on specific attributes.
Args:
src_rev (object): The source revision object to compare.
dest_rev (object): The destination revision object to compare.
case_sensitive (bool, optional): Flag to indicate if the comparison should be case sensitive. Defaults to False.
Returns:
bool: True if all specified attributes match between the two revisions, False otherwise.
"""
return all(
db.BaseWrapper.compare_attrs(
src_rev,
dest_rev,
["RevisionDate", "Description", "IssuedBy", "IssuedTo"],
case_sensitive=case_sensitive,
)
)
``` | ### `get_all_views(doc=None, view_types=None, include_nongraphical=False)` Retrieves all views from the given Revit document, with optional filtering by view types and graphical views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve views from. If None, defaults to DOCS.doc. | `None` | | `view_types` | `list` | A list of view types to filter the views. If None, no filtering is applied. | `None` | | `include_nongraphical` | `bool` | If True, includes non-graphical views in the result. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of views from the Revit document, filtered by the specified criteria. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
``` | ```md-code__content
def get_all_views(doc=None, view_types=None, include_nongraphical=False):
"""
Retrieves all views from the given Revit document, with optional filtering by view types and graphical views.
Args:
doc (Document, optional): The Revit document to retrieve views from. If None, defaults to DOCS.doc.
view_types (list, optional): A list of view types to filter the views. If None, no filtering is applied.
include_nongraphical (bool, optional): If True, includes non-graphical views in the result. Defaults to False.
Returns:
list: A list of views from the Revit document, filtered by the specified criteria.
"""
doc = doc or DOCS.doc
all_views = (
DB.FilteredElementCollector(doc)
.OfClass(DB.View)
.WhereElementIsNotElementType()
.ToElements()
)
if view_types:
all_views = [x for x in all_views if x.ViewType in view_types]
if not include_nongraphical:
return [
x
for x in all_views
if x.ViewType in GRAPHICAL_VIEWTYPES
and not x.IsTemplate
and not x.ViewSpecific
]
return all_views
``` | ### `get_all_view_templates(doc=None, view_types=None)` Retrieves all view templates from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for view templates.
If None, the active document will be used. | `None` | | `view_types` | `list` | A list of view types to filter the views.
If None, all view types will be considered. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of view templates found in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
``` | ```md-code__content
def get_all_view_templates(doc=None, view_types=None):
"""
Retrieves all view templates from the given Revit document.
Args:
doc (Document, optional): The Revit document to search for view templates.
If None, the active document will be used.
view_types (list, optional): A list of view types to filter the views.
If None, all view types will be considered.
Returns:
list: A list of view templates found in the document.
"""
return [
x
for x in get_all_views(
doc=doc, view_types=view_types, include_nongraphical=True
)
if x.IsTemplate
]
``` | ### `get_sheet_by_number(sheet_num, doc=None)` Retrieves a sheet from the document by its sheet number. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sheet_num` | `str` | The sheet number to search for. | _required_ | | `doc` | `Document` | The Revit document to search within.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `Element` | | The sheet element with the specified sheet number,
or None if no matching sheet is found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
``` | ```md-code__content
def get_sheet_by_number(sheet_num, doc=None):
"""
Retrieves a sheet from the document by its sheet number.
Args:
sheet_num (str): The sheet number to search for.
doc (Document, optional): The Revit document to search within.
If not provided, defaults to DOCS.doc.
Returns:
Element: The sheet element with the specified sheet number,
or None if no matching sheet is found.
"""
doc = doc or DOCS.doc
return next((x for x in get_sheets(doc=doc) if x.SheetNumber == sheet_num), None)
``` | ### `get_viewport_by_number(sheet_num, detail_num, doc=None)` Retrieves a viewport from a Revit document based on the sheet number and detail number. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sheet_num` | `str` | The number of the sheet containing the viewport. | _required_ | | `detail_num` | `str` | The detail number of the viewport to retrieve. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `Element` | | The viewport element if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
``` | ```md-code__content
def get_viewport_by_number(sheet_num, detail_num, doc=None):
"""
Retrieves a viewport from a Revit document based on the sheet number and detail number.
Args:
sheet_num (str): The number of the sheet containing the viewport.
detail_num (str): The detail number of the viewport to retrieve.
doc (Document, optional): The Revit document to search in. If not provided, defaults to DOCS.doc.
Returns:
Element: The viewport element if found, otherwise None.
"""
doc = doc or DOCS.doc
sheet = get_sheet_by_number(sheet_num, doc=doc)
if sheet:
vps = [doc.GetElement(x) for x in sheet.GetAllViewports()]
for vp in vps:
det_num = vp.Parameter[
DB.BuiltInParameter.VIEWPORT_DETAIL_NUMBER
].AsString()
if det_num == detail_num:
return vp
``` | ### `get_view_by_sheetref(sheet_num, detail_num, doc=None)` Retrieves the view ID associated with a given sheet number and detail number. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `sheet_num` | `int` | The sheet number to search for. | _required_ | | `detail_num` | `int` | The detail number to search for. | _required_ | | `doc` | `Document` | The Revit document to search within. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `ElementId` | | The ID of the view associated with the specified sheet and detail numbers, or None if not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
``` | ```md-code__content
def get_view_by_sheetref(sheet_num, detail_num, doc=None):
"""
Retrieves the view ID associated with a given sheet number and detail number.
Args:
sheet_num (int): The sheet number to search for.
detail_num (int): The detail number to search for.
doc (Document, optional): The Revit document to search within. If not provided, defaults to DOCS.doc.
Returns:
ElementId: The ID of the view associated with the specified sheet and detail numbers, or None if not found.
"""
doc = doc or DOCS.doc
vport = get_viewport_by_number(sheet_num, detail_num, doc=doc)
if vport:
return vport.ViewId
``` | ### `is_schedule(view)` Determines if the given view is a schedule that is not a template, title block revision schedule, internal keynote schedule, or keynote legend. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the view is a schedule and not one of the excluded types, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
``` | ```md-code__content
def is_schedule(view):
"""
Determines if the given view is a schedule that is not a template,
title block revision schedule, internal keynote schedule, or keynote legend.
Args:
view (DB.View): The Revit view to check.
Returns:
bool: True if the view is a schedule and not one of the excluded types, False otherwise.
"""
if isinstance(view, DB.ViewSchedule) and not view.IsTemplate:
isrevsched = view.IsTitleblockRevisionSchedule
isintkeynote = view.IsInternalKeynoteSchedule
iskeynotelegend = (
view.Definition.CategoryId
== get_category(DB.BuiltInCategory.OST_KeynoteTags).Id
)
return not (isrevsched or isintkeynote or iskeynotelegend)
return False
``` | ### `get_all_schedules(doc=None)` Retrieves all schedule views from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve schedules from.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `filter` | | A filter object containing all schedule views in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
``` | ```md-code__content
def get_all_schedules(doc=None):
"""
Retrieves all schedule views from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve schedules from.
If not provided, defaults to DOCS.doc.
Returns:
filter: A filter object containing all schedule views in the document.
"""
doc = doc or DOCS.doc
all_scheds = (
DB.FilteredElementCollector(doc)
.OfClass(DB.ViewSchedule)
.WhereElementIsNotElementType()
.ToElements()
)
return filter(is_schedule, all_scheds)
``` | ### `get_view_by_name(view_name, view_types=None, doc=None)` Retrieves a Revit view by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view_name` | `str` | The name of the view to retrieve. | _required_ | | `view_types` | `list` | A list of view types to filter the search. Defaults to None. | `None` | | `doc` | `Document` | The Revit document to search within. Defaults to the active document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `View` | | The Revit view that matches the given name, or None if no match is found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
``` | ```md-code__content
def get_view_by_name(view_name, view_types=None, doc=None):
"""
Retrieves a Revit view by its name.
Args:
view_name (str): The name of the view to retrieve.
view_types (list, optional): A list of view types to filter the search. Defaults to None.
doc (Document, optional): The Revit document to search within. Defaults to the active document.
Returns:
View: The Revit view that matches the given name, or None if no match is found.
"""
doc = doc or DOCS.doc
for view in get_all_views(doc=doc, view_types=view_types):
if get_name(view) == view_name:
return view
``` | ### `get_all_referencing_elements(doc=None)` Retrieves all elements in the given Revit document that reference views. This function collects all elements in the provided Revit document that are not element types, belong to a category, are instances of DB.Element, and whose category is in the predefined set of view-related built-in categories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for referencing elements.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | list\[DB.ElementId\]: A list of element IDs that reference views in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
``` | ```md-code__content
def get_all_referencing_elements(doc=None):
"""
Retrieves all elements in the given Revit document that reference views.
This function collects all elements in the provided Revit document that are not element types,
belong to a category, are instances of DB.Element, and whose category is in the predefined
set of view-related built-in categories.
Args:
doc (DB.Document, optional): The Revit document to search for referencing elements.
If not provided, defaults to DOCS.doc.
Returns:
list[DB.ElementId]: A list of element IDs that reference views in the document.
"""
doc = doc or DOCS.doc
all_referencing_elements = []
for el in (
DB.FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
):
if (
el.Category
and isinstance(el, DB.Element)
and get_builtincategory(el.Category) in BUILTINCATEGORIES_VIEW
):
all_referencing_elements.append(el.Id)
return all_referencing_elements
``` | ### `get_all_referencing_elements_in_view(view)` Retrieves all elements in the given view that reference other elements. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view from which to collect referencing elements. | _required_ | Returns: | Type | Description | | --- | --- | | | list\[DB.ElementId\]: A list of element IDs that reference other elements in the view. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
``` | ```md-code__content
def get_all_referencing_elements_in_view(view):
"""
Retrieves all elements in the given view that reference other elements.
Args:
view (DB.View): The Revit view from which to collect referencing elements.
Returns:
list[DB.ElementId]: A list of element IDs that reference other elements in the view.
"""
all_referencing_elements_in_view = []
for el in (
DB.FilteredElementCollector(view.Document, view.Id)
.WhereElementIsNotElementType()
.ToElements()
):
if (
el.Category
and isinstance(el, DB.Element)
and get_builtincategory(el.Category) in BUILTINCATEGORIES_VIEW
):
all_referencing_elements_in_view.append(el.Id)
return all_referencing_elements_in_view
``` | ### `get_schedules_on_sheet(viewsheet, doc=None)` Retrieves all schedule instances placed on a given Revit view sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `viewsheet` | `ViewSheet` | The Revit view sheet from which to retrieve schedule instances. | _required_ | | `doc` | `Document` | The Revit document. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of schedule instances (DB.ScheduleSheetInstance) that are placed on the given view sheet,
excluding title block revision schedules. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
``` | ```md-code__content
def get_schedules_on_sheet(viewsheet, doc=None):
"""
Retrieves all schedule instances placed on a given Revit view sheet.
Args:
viewsheet (DB.ViewSheet): The Revit view sheet from which to retrieve schedule instances.
doc (DB.Document, optional): The Revit document. If not provided, defaults to DOCS.doc.
Returns:
list: A list of schedule instances (DB.ScheduleSheetInstance) that are placed on the given view sheet,
excluding title block revision schedules.
"""
doc = doc or DOCS.doc
all_sheeted_scheds = (
DB.FilteredElementCollector(doc).OfClass(DB.ScheduleSheetInstance).ToElements()
)
return [
x
for x in all_sheeted_scheds
if x.OwnerViewId == viewsheet.Id
and not doc.GetElement(x.ScheduleId).IsTitleblockRevisionSchedule
]
``` | ### `get_schedules_instances(doc=None)` Retrieves all schedule instances placed on sheets. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search within. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Type | Description | | --- | --- | | | List\[ScheduleSheetInstance\]: A list of ScheduleSheetInstance elements. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
``` | ```md-code__content
def get_schedules_instances(doc=None):
"""
Retrieves all schedule instances placed on sheets.
Args:
doc (Document, optional): The Revit document to search within. If not provided,
the default document (DOCS.doc) will be used.
Returns:
List[ScheduleSheetInstance]: A list of ScheduleSheetInstance elements.
"""
return (
DB.FilteredElementCollector(doc or DOCS.doc)
.OfClass(DB.ScheduleSheetInstance)
.ToElements()
)
``` | ### `is_sheet_empty(viewsheet)` Checks if a given Revit sheet is empty. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `viewsheet` | | The Revit sheet to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the sheet has no viewports or schedules, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
``` | ```md-code__content
def is_sheet_empty(viewsheet):
"""
Checks if a given Revit sheet is empty.
Args:
viewsheet: The Revit sheet to check.
Returns:
bool: True if the sheet has no viewports or schedules, False otherwise.
"""
sheet_views = viewsheet.GetAllViewports()
sheet_scheds = get_schedules_on_sheet(viewsheet, doc=viewsheet.Document)
if sheet_views or sheet_scheds:
return False
return True
``` | ### `get_doc_categories(doc=None, include_subcats=True)` Retrieves all categories from the given Revit document, optionally including subcategories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve categories.
If not provided, defaults to DOCS.doc. | `None` | | `include_subcats` | `bool` | Whether to include subcategories in the result.
Defaults to True. | `True` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of all categories (and subcategories, if include\_subcats is True) in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
``` | ```md-code__content
def get_doc_categories(doc=None, include_subcats=True):
"""
Retrieves all categories from the given Revit document, optionally including subcategories.
Args:
doc (Document, optional): The Revit document from which to retrieve categories.
If not provided, defaults to DOCS.doc.
include_subcats (bool, optional): Whether to include subcategories in the result.
Defaults to True.
Returns:
list: A list of all categories (and subcategories, if include_subcats is True) in the document.
"""
doc = doc or DOCS.doc
all_cats = []
cats = doc.Settings.Categories
all_cats.extend(cats)
if include_subcats:
for cat in cats:
all_cats.extend([x for x in cat.SubCategories])
return all_cats
``` | ### `get_schedule_categories(doc=None)` Retrieves the categories that are valid for schedules in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve the schedule categories from.
If not provided, it defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of categories that are valid for schedules in the given Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
``` | ```md-code__content
def get_schedule_categories(doc=None):
"""
Retrieves the categories that are valid for schedules in the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve the schedule categories from.
If not provided, it defaults to DOCS.doc.
Returns:
list: A list of categories that are valid for schedules in the given Revit document.
"""
doc = doc or DOCS.doc
all_cats = get_doc_categories(doc)
cats = []
for cat_id in DB.ViewSchedule.GetValidCategoriesForSchedule():
for cat in all_cats:
if cat.Id == cat_id:
cats.append(cat)
return cats
``` | ### `get_key_schedule_categories(doc=None)` Retrieves the categories that are valid for key schedules in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve categories from.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of categories that are valid for key schedules. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
``` | ```md-code__content
def get_key_schedule_categories(doc=None):
"""
Retrieves the categories that are valid for key schedules in the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve categories from.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of categories that are valid for key schedules.
"""
doc = doc or DOCS.doc
all_cats = get_doc_categories(doc)
cats = []
for cat_id in DB.ViewSchedule.GetValidCategoriesForKeySchedule():
for cat in all_cats:
if cat.Id == cat_id:
cats.append(cat)
return cats
``` | ### `get_takeoff_categories(doc=None)` Retrieves the categories that are valid for material takeoff schedules in a given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve categories from. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of categories that are valid for material takeoff schedules. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
``` | ```md-code__content
def get_takeoff_categories(doc=None):
"""
Retrieves the categories that are valid for material takeoff schedules in a given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve categories from. If not provided,
the default document (DOCS.doc) will be used.
Returns:
list: A list of categories that are valid for material takeoff schedules.
"""
doc = doc or DOCS.doc
all_cats = get_doc_categories(doc)
cats = []
for cat_id in DB.ViewSchedule.GetValidCategoriesForMaterialTakeoff():
for cat in all_cats:
if cat.Id == cat_id:
cats.append(cat)
return cats
``` | ### `get_category(cat_name_or_builtin, doc=None)` Retrieves a Revit category based on the provided category name, built-in category, or category object. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `Union[str, BuiltInCategory, Category]` | The category name as a string,
a built-in category enum, or a category object. | _required_ | | `doc` | `Optional[Document]` | The Revit document to search within. If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | DB.Category: The matching Revit category object, or None if no match is found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
``` | ```md-code__content
def get_category(cat_name_or_builtin, doc=None):
"""
Retrieves a Revit category based on the provided category name, built-in category, or category object.
Args:
cat_name_or_builtin (Union[str, DB.BuiltInCategory, DB.Category]): The category name as a string,
a built-in category enum, or a category object.
doc (Optional[Document]): The Revit document to search within. If not provided, defaults to DOCS.doc.
Returns:
DB.Category: The matching Revit category object, or None if no match is found.
"""
doc = doc or DOCS.doc
all_cats = get_doc_categories(doc)
if isinstance(cat_name_or_builtin, str):
for cat in all_cats:
if cat.Name == cat_name_or_builtin:
return cat
elif isinstance(cat_name_or_builtin, DB.BuiltInCategory):
get_elementid_value = get_elementid_value_func()
for cat in all_cats:
if get_elementid_value(cat.Id) == int(cat_name_or_builtin):
return cat
elif isinstance(cat_name_or_builtin, DB.Category):
return cat_name_or_builtin
``` | ### `get_builtincategory(cat_name_or_id, doc=None)` Retrieves the BuiltInCategory for a given category name or ElementId. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_id` | `str or ElementId` | The name of the category as a string or the ElementId of the category. | _required_ | | `doc` | `optional` | The Revit document. If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | DB.BuiltInCategory: The corresponding BuiltInCategory if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
``` | ```md-code__content
def get_builtincategory(cat_name_or_id, doc=None):
"""
Retrieves the BuiltInCategory for a given category name or ElementId.
Args:
cat_name_or_id (str or DB.ElementId): The name of the category as a string or the ElementId of the category.
doc (optional): The Revit document. If not provided, defaults to DOCS.doc.
Returns:
DB.BuiltInCategory: The corresponding BuiltInCategory if found, otherwise None.
"""
doc = doc or DOCS.doc
cat_id = None
if isinstance(cat_name_or_id, str):
cat = get_category(cat_name_or_id)
if cat:
cat_id = cat.Id
elif isinstance(cat_name_or_id, DB.ElementId):
cat_id = cat_name_or_id
if cat_id:
get_elementid_value = get_elementid_value_func()
for bicat in DB.BuiltInCategory.GetValues(DB.BuiltInCategory):
if int(bicat) == get_elementid_value(cat_id):
return bicat
``` | ### `get_subcategories(doc=None, purgable=False, filterfunc=None)` Retrieves subcategories from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve subcategories from.
If None, defaults to DOCS.doc. | `None` | | `purgable` | `bool` | If True, only includes subcategories that are purgable
(element ID value greater than 1). Defaults to False. | `False` | | `filterfunc` | `function` | A function to filter the subcategories.
If provided, only subcategories that satisfy
the filter function will be included. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of subcategories from the given Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
``` | ```md-code__content
def get_subcategories(doc=None, purgable=False, filterfunc=None):
"""
Retrieves subcategories from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve subcategories from.
If None, defaults to DOCS.doc.
purgable (bool, optional): If True, only includes subcategories that are purgable
(element ID value greater than 1). Defaults to False.
filterfunc (function, optional): A function to filter the subcategories.
If provided, only subcategories that satisfy
the filter function will be included.
Returns:
list: A list of subcategories from the given Revit document.
"""
doc = doc or DOCS.doc
# collect custom categories
subcategories = []
get_elementid_value = get_elementid_value_func()
for cat in doc.Settings.Categories:
for subcat in cat.SubCategories:
if purgable:
if get_elementid_value(subcat.Id) > 1:
subcategories.append(subcat)
else:
subcategories.append(subcat)
if filterfunc:
subcategories = filter(filterfunc, subcategories)
return subcategories
``` | ### `get_subcategory(cat_name_or_builtin, subcategory_name, doc=None)` Retrieves a subcategory from a given category in a Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `cat_name_or_builtin` | `str or BuiltInCategory` | The name of the category or a built-in category. | _required_ | | `subcategory_name` | `str` | The name of the subcategory to retrieve. | _required_ | | `doc` | `Document` | The Revit document to search in. Defaults to the active document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `Category` | | The subcategory if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
``` | ```md-code__content
def get_subcategory(cat_name_or_builtin, subcategory_name, doc=None):
"""
Retrieves a subcategory from a given category in a Revit document.
Args:
cat_name_or_builtin (str or BuiltInCategory): The name of the category or a built-in category.
subcategory_name (str): The name of the subcategory to retrieve.
doc (Document, optional): The Revit document to search in. Defaults to the active document.
Returns:
Category: The subcategory if found, otherwise None.
"""
doc = doc or DOCS.doc
cat = get_category(cat_name_or_builtin)
if cat:
for subcat in cat.SubCategories:
if subcat.Name == subcategory_name:
return subcat
``` | ### `get_builtinparameter(element, param_name, doc=None)` Retrieves the built-in parameter associated with a given element and parameter name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element from which to retrieve the parameter. | _required_ | | `param_name` | `str` | The name of the parameter to look up. | _required_ | | `doc` | `Document` | The Revit document. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `BuiltInParameter` | | The built-in parameter corresponding to the given element and parameter name. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the parameter with the given name is not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
``` | ```md-code__content
def get_builtinparameter(element, param_name, doc=None):
"""
Retrieves the built-in parameter associated with a given element and parameter name.
Args:
element (Element): The Revit element from which to retrieve the parameter.
param_name (str): The name of the parameter to look up.
doc (Document, optional): The Revit document. If not provided, defaults to DOCS.doc.
Returns:
BuiltInParameter: The built-in parameter corresponding to the given element and parameter name.
Raises:
PyRevitException: If the parameter with the given name is not found.
"""
doc = doc or DOCS.doc
eparam = element.LookupParameter(param_name)
if eparam:
eparam_def_id = eparam.Definition.Id
get_elementid_value = get_elementid_value_func()
for biparam in DB.BuiltInParameter.GetValues(DB.BuiltInParameter):
if int(biparam) == get_elementid_value(eparam_def_id):
return biparam
else:
raise PyRevitException("Parameter not found: {}".format(param_name))
``` | ### `get_view_cutplane_offset(view)` Retrieves the offset of the cut plane for a given Revit view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view from which to get the cut plane offset. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `float` | | The offset of the cut plane in the view. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
``` | ```md-code__content
def get_view_cutplane_offset(view):
"""
Retrieves the offset of the cut plane for a given Revit view.
Args:
view (Autodesk.Revit.DB.View): The Revit view from which to get the cut plane offset.
Returns:
float: The offset of the cut plane in the view.
"""
viewrange = view.GetViewRange()
return viewrange.GetOffset(DB.PlanViewPlane.CutPlane)
``` | ### `get_project_location_transform(doc=None)` Retrieves the transformation matrix of the active project location in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to get the project location transform.
If not provided, it defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `Transform` | | The transformation matrix of the active project location. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
``` | ```md-code__content
def get_project_location_transform(doc=None):
"""
Retrieves the transformation matrix of the active project location in the given Revit document.
Args:
doc (Document, optional): The Revit document from which to get the project location transform.
If not provided, it defaults to DOCS.doc.
Returns:
Transform: The transformation matrix of the active project location.
"""
doc = doc or DOCS.doc
return doc.ActiveProjectLocation.GetTransform()
``` | ### `get_all_linkedmodels(doc=None)` Retrieves all linked Revit models in the given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for linked models.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | List\[Element\]: A list of RevitLinkType elements representing the linked models. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
``` | ```md-code__content
def get_all_linkedmodels(doc=None):
"""
Retrieves all linked Revit models in the given document.
Args:
doc (Document, optional): The Revit document to search for linked models.
If not provided, defaults to DOCS.doc.
Returns:
List[Element]: A list of RevitLinkType elements representing the linked models.
"""
doc = doc or DOCS.doc
return DB.FilteredElementCollector(doc).OfClass(DB.RevitLinkType).ToElements()
``` | ### `get_all_linkeddocs(doc=None)` Retrieves all linked documents in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for linked documents.
If None, it defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of linked Revit documents. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
``` | ```md-code__content
def get_all_linkeddocs(doc=None):
"""
Retrieves all linked documents in the given Revit document.
Args:
doc (Document, optional): The Revit document to search for linked documents.
If None, it defaults to DOCS.doc.
Returns:
list: A list of linked Revit documents.
"""
doc = doc or DOCS.doc
linkinstances = (
DB.FilteredElementCollector(doc).OfClass(DB.RevitLinkInstance).ToElements()
)
docs = [x.GetLinkDocument() for x in linkinstances]
return [x for x in docs if x]
``` | ### `get_all_grids(group_by_direction=False, include_linked_models=False, doc=None)` Retrieves all grid elements from the given Revit document and optionally from linked models. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `group_by_direction` | `bool` | If True, groups the grids by their direction. | `False` | | `include_linked_models` | `bool` | If True, includes grids from linked models. | `False` | | `doc` | `Document` | The Revit document to retrieve grids from. If None, uses the current document. | `None` | Returns: | Type | Description | | --- | --- | | | list or dict: A list of all grid elements if group\_by\_direction is False.
A dictionary grouping grid elements by their direction if group\_by\_direction is True. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
``` | ```md-code__content
def get_all_grids(group_by_direction=False, include_linked_models=False, doc=None):
"""
Retrieves all grid elements from the given Revit document and optionally from linked models.
Args:
group_by_direction (bool): If True, groups the grids by their direction.
include_linked_models (bool): If True, includes grids from linked models.
doc (Document, optional): The Revit document to retrieve grids from. If None, uses the current document.
Returns:
list or dict: A list of all grid elements if group_by_direction is False.
A dictionary grouping grid elements by their direction if group_by_direction is True.
"""
doc = doc or DOCS.doc
target_docs = [doc]
if include_linked_models:
target_docs.extend(get_all_linkeddocs())
all_grids = []
for tdoc in target_docs:
if tdoc is not None:
all_grids.extend(
list(
DB.FilteredElementCollector(tdoc)
.OfCategory(DB.BuiltInCategory.OST_Grids)
.WhereElementIsNotElementType()
.ToElements()
)
)
if group_by_direction:
direcs = {db.XYZPoint(x.Curve.Direction) for x in all_grids}
grouped_grids = {}
for direc in direcs:
grouped_grids[direc] = [
x for x in all_grids if direc == db.XYZPoint(x.Curve.Direction)
]
return grouped_grids
return all_grids
``` | ### `get_gridpoints(grids=None, include_linked_models=False, doc=None)` Retrieves the intersection points of grid lines in a Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `grids` | `list` | A list of grid elements to consider. If None, all grids in the document are considered. | `None` | | `include_linked_models` | `bool` | If True, includes grids from linked models. Defaults to False. | `False` | | `doc` | `Document` | The Revit document to operate on. If None, uses the current active document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of GridPoint objects representing the intersection points of the grid lines. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
``` | ```md-code__content
def get_gridpoints(grids=None, include_linked_models=False, doc=None):
"""
Retrieves the intersection points of grid lines in a Revit document.
Args:
grids (list, optional): A list of grid elements to consider. If None, all grids in the document are considered.
include_linked_models (bool, optional): If True, includes grids from linked models. Defaults to False.
doc (Document, optional): The Revit document to operate on. If None, uses the current active document.
Returns:
list: A list of GridPoint objects representing the intersection points of the grid lines.
"""
doc = doc or DOCS.doc
source_grids = grids or get_all_grids(
doc=doc, include_linked_models=include_linked_models
)
gints = {}
for grid1 in source_grids:
for grid2 in source_grids:
results = framework.clr.Reference[DB.IntersectionResultArray]()
intres = grid1.Curve.Intersect(grid2.Curve, results)
if intres == DB.SetComparisonResult.Overlap:
gints[db.XYZPoint(results.get_Item(0).XYZPoint)] = [grid1, grid2]
return [GridPoint(point=k, grids=v) for k, v in gints.items()]
``` | ### `get_closest_gridpoint(element, gridpoints)` Finds the closest grid point to a given element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The element for which the closest grid point is to be found.
It is expected to have a Location attribute with a Point property. | _required_ | | `gridpoints` | | A list of grid points. Each grid point is expected to have a
point attribute with an unwrap() method that returns an object
with a DistanceTo method. | _required_ | Returns: | Type | Description | | --- | --- | | | The grid point that is closest to the given element. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
``` | ```md-code__content
def get_closest_gridpoint(element, gridpoints):
"""
Finds the closest grid point to a given element.
Args:
element: The element for which the closest grid point is to be found.
It is expected to have a Location attribute with a Point property.
gridpoints: A list of grid points. Each grid point is expected to have a
point attribute with an unwrap() method that returns an object
with a DistanceTo method.
Returns:
The grid point that is closest to the given element.
"""
dist = (
gridpoints[0].point.unwrap().DistanceTo(element.Location.Point),
gridpoints[0],
)
for grid_point in gridpoints:
gp_dist = grid_point.point.unwrap().DistanceTo(element.Location.Point)
if gp_dist < dist[0]:
dist = (gp_dist, grid_point)
return dist[1]
``` | ### `get_category_set(category_list, doc=None)` Creates a CategorySet from a list of built-in categories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `category_list` | `list` | A list of built-in categories to include in the CategorySet. | _required_ | | `doc` | `Document` | The Revit document to use. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `CategorySet` | | A set of categories created from the provided list. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
``` | ```md-code__content
def get_category_set(category_list, doc=None):
"""
Creates a CategorySet from a list of built-in categories.
Args:
category_list (list): A list of built-in categories to include in the CategorySet.
doc (Document, optional): The Revit document to use. If not provided, defaults to DOCS.doc.
Returns:
CategorySet: A set of categories created from the provided list.
"""
doc = doc or DOCS.doc
cat_set = HOST_APP.app.Create.NewCategorySet()
for builtin_cat in category_list:
cat = doc.Settings.Categories.get_Item(builtin_cat)
cat_set.Insert(cat)
return cat_set
``` | ### `get_all_category_set(bindable=True, doc=None)` Retrieves a set of all categories in the Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `bindable` | `bool` | If True, only includes categories that allow bound parameters. Defaults to True. | `True` | | `doc` | `Document` | The Revit document to retrieve categories from. If None, uses the default document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `CategorySet` | | A set of categories from the specified Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
``` | ```md-code__content
def get_all_category_set(bindable=True, doc=None):
"""
Retrieves a set of all categories in the Revit document.
Args:
bindable (bool, optional): If True, only includes categories that allow bound parameters. Defaults to True.
doc (Document, optional): The Revit document to retrieve categories from. If None, uses the default document.
Returns:
CategorySet: A set of categories from the specified Revit document.
"""
doc = doc or DOCS.doc
cat_set = HOST_APP.app.Create.NewCategorySet()
for cat in doc.Settings.Categories:
if bindable:
if cat.AllowsBoundParameters:
cat_set.Insert(cat)
else:
cat_set.Insert(cat)
return cat_set
``` | ### `get_rule_filters(doc=None)` Retrieves a list of rule-based filters from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve the filters from.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of ParameterFilterElement instances from the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
``` | ```md-code__content
def get_rule_filters(doc=None):
"""
Retrieves a list of rule-based filters from the given Revit document.
Args:
doc (DB.Document, optional): The Revit document to retrieve the filters from.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of ParameterFilterElement instances from the document.
"""
doc = doc or DOCS.doc
rfcl = (
DB.FilteredElementCollector(doc)
.OfClass(DB.ParameterFilterElement)
.WhereElementIsNotElementType()
.ToElements()
)
return list(rfcl)
``` | ### `get_connected_circuits(element, spare=False, space=False)` Retrieves the electrical circuits connected to a given element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element to get connected circuits for. | _required_ | | `spare` | `bool` | Include spare circuits if True. Defaults to False. | `False` | | `space` | `bool` | Include space circuits if True. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of electrical systems connected to the element that match the specified circuit types. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
``` | ```md-code__content
def get_connected_circuits(element, spare=False, space=False):
"""
Retrieves the electrical circuits connected to a given element.
Args:
element (DB.Element): The Revit element to get connected circuits for.
spare (bool, optional): Include spare circuits if True. Defaults to False.
space (bool, optional): Include space circuits if True. Defaults to False.
Returns:
list: A list of electrical systems connected to the element that match the specified circuit types.
"""
circuit_types = [DB.Electrical.CircuitType.Circuit]
if spare:
circuit_types.append(DB.Electrical.CircuitType.Spare)
if space:
circuit_types.append(DB.Electrical.CircuitType.Space)
if HOST_APP.is_newer_than(
2021, or_equal=True
): # deprecation of ElectricalSystems in 2021
if element.MEPModel and element.MEPModel.GetElectricalSystems():
return [
x
for x in element.MEPModel.GetElectricalSystems()
if x.CircuitType in circuit_types
]
else:
if element.MEPModel and element.MEPModel.ElectricalSystems:
return [
x
for x in element.MEPModel.ElectricalSystems
if x.CircuitType in circuit_types
]
``` | ### `get_element_categories(elements)` Given a list of Revit elements, returns a list of unique categories. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `elements` | `list` | A list of Revit elements. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of unique categories of the given elements. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
``` | ```md-code__content
def get_element_categories(elements):
"""
Given a list of Revit elements, returns a list of unique categories.
Args:
elements (list): A list of Revit elements.
Returns:
list: A list of unique categories of the given elements.
"""
catsdict = {x.Category.Name: x.Category for x in elements}
uniquenames = set(catsdict.keys())
return [catsdict[x] for x in uniquenames]
``` | ### `get_category_schedules(category_or_catname, doc=None)` Retrieves all schedules for a given category in a Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `category_or_catname` | `str or Category` | The category or category name to filter schedules. | _required_ | | `doc` | `Document` | The Revit document to search in. Defaults to None, in which case the default document is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of schedules that belong to the specified category. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
``` | ```md-code__content
def get_category_schedules(category_or_catname, doc=None):
"""
Retrieves all schedules for a given category in a Revit document.
Args:
category_or_catname (str or Category): The category or category name to filter schedules.
doc (Document, optional): The Revit document to search in. Defaults to None, in which case the default document is used.
Returns:
list: A list of schedules that belong to the specified category.
"""
doc = doc or DOCS.doc
cat = get_category(category_or_catname)
scheds = get_all_schedules(doc=doc)
return [x for x in scheds if x.Definition.CategoryId == cat.Id]
``` | ### `get_schedule_field(schedule, field_name)` Retrieves a specific field from a Revit schedule by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `schedule` | `Schedule` | The Revit schedule object. | _required_ | | `field_name` | `str` | The name of the field to retrieve. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `ScheduleField` | | The field object if found, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
``` | ```md-code__content
def get_schedule_field(schedule, field_name):
"""
Retrieves a specific field from a Revit schedule by its name.
Args:
schedule (Schedule): The Revit schedule object.
field_name (str): The name of the field to retrieve.
Returns:
ScheduleField: The field object if found, otherwise None.
"""
for field_idx in schedule.Definition.GetFieldOrder():
field = schedule.Definition.GetField(field_idx)
if field.GetName() == field_name:
return field
``` | ### `get_schedule_filters(schedule, field_name, return_index=False)` Retrieves the filters applied to a schedule based on a specified field name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `schedule` | `Schedule` | The schedule from which to retrieve filters. | _required_ | | `field_name` | `str` | The name of the field to match filters against. | _required_ | | `return_index` | `bool` | If True, returns the indices of the matching filters.
If False, returns the filter objects. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of matching filters or their indices, depending on the value of return\_index. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
``` | ```md-code__content
def get_schedule_filters(schedule, field_name, return_index=False):
"""
Retrieves the filters applied to a schedule based on a specified field name.
Args:
schedule (Schedule): The schedule from which to retrieve filters.
field_name (str): The name of the field to match filters against.
return_index (bool, optional): If True, returns the indices of the matching filters.
If False, returns the filter objects. Defaults to False.
Returns:
list: A list of matching filters or their indices, depending on the value of return_index.
"""
matching_filters = []
field = get_schedule_field(schedule, field_name)
if field:
for idx, sfilter in enumerate(schedule.Definition.GetFilters()):
if sfilter.FieldId == field.FieldId:
if return_index:
matching_filters.append(idx)
else:
matching_filters.append(sfilter)
return matching_filters
``` | ### `get_sheet_tblocks(src_sheet)` Retrieves all title block elements from a given Revit sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `src_sheet` | `ViewSheet` | The source Revit sheet from which to collect title blocks. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of title block elements present on the specified sheet. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
``` | ```md-code__content
def get_sheet_tblocks(src_sheet):
"""
Retrieves all title block elements from a given Revit sheet.
Args:
src_sheet (DB.ViewSheet): The source Revit sheet from which to collect title blocks.
Returns:
list: A list of title block elements present on the specified sheet.
"""
sheet_tblocks = (
DB.FilteredElementCollector(src_sheet.Document, src_sheet.Id)
.OfCategory(DB.BuiltInCategory.OST_TitleBlocks)
.WhereElementIsNotElementType()
.ToElements()
)
return list(sheet_tblocks)
``` | ### `get_sheet_sets(doc=None)` Retrieves all sheet sets from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve sheet sets from.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of ViewSheetSet elements from the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
``` | ```md-code__content
def get_sheet_sets(doc=None):
"""
Retrieves all sheet sets from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve sheet sets from.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of ViewSheetSet elements from the document.
"""
doc = doc or DOCS.doc
sheet_sets = (
DB.FilteredElementCollector(doc)
.OfClass(DB.ViewSheetSet)
.WhereElementIsNotElementType()
.ToElements()
)
return list(sheet_sets)
``` | ### `get_rev_number(revision, sheet=None)` Get the revision number for a given revision. If a sheet is provided and it is an instance of DB.ViewSheet, the function returns the revision number as it appears on the sheet. Otherwise, it returns the sequence number of the revision or the revision number if it exists. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `revision` | `Revision` | The revision object to get the number for. | _required_ | | `sheet` | `ViewSheet` | The sheet object to get the revision number from. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The revision number as a string. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
``` | ```md-code__content
def get_rev_number(revision, sheet=None):
"""
Get the revision number for a given revision.
If a sheet is provided and it is an instance of DB.ViewSheet, the function
returns the revision number as it appears on the sheet. Otherwise, it returns
the sequence number of the revision or the revision number if it exists.
Args:
revision (DB.Revision): The revision object to get the number for.
sheet (DB.ViewSheet, optional): The sheet object to get the revision number from. Defaults to None.
Returns:
str: The revision number as a string.
"""
# if sheet is provided, get number on sheet
if sheet and isinstance(sheet, DB.ViewSheet):
return sheet.GetRevisionNumberOnSheet(revision.Id)
# otherwise get number from revision
revnum = revision.SequenceNumber
if hasattr(revision, "RevisionNumber"):
revnum = revision.RevisionNumber
return revnum
``` | ### `get_pointclouds(doc=None)` Retrieves all point cloud elements from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for point cloud elements.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of point cloud elements found in the specified document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
``` | ```md-code__content
def get_pointclouds(doc=None):
"""
Retrieves all point cloud elements from the given Revit document.
Args:
doc (Document, optional): The Revit document to search for point cloud elements.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of point cloud elements found in the specified document.
"""
doc = doc or DOCS.doc
return get_elements_by_categories([DB.BuiltInCategory.OST_PointClouds], doc=doc)
``` | ### `get_mep_connections(element)` Retrieves the MEP (Mechanical, Electrical, and Plumbing) connections for a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element for which to retrieve MEP connections. This can be a
FamilyInstance or a Plumbing Pipe. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of elements that are connected to the given element through MEP connections. | Returns an empty list if no connections are found or if the element does not have a ConnectorManager. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
``` | ```md-code__content
def get_mep_connections(element):
"""
Retrieves the MEP (Mechanical, Electrical, and Plumbing) connections for a given Revit element.
Args:
element (DB.Element): The Revit element for which to retrieve MEP connections. This can be a
FamilyInstance or a Plumbing Pipe.
Returns:
list: A list of elements that are connected to the given element through MEP connections.
Returns an empty list if no connections are found or if the element does not have a
ConnectorManager.
"""
connmgr = None
if isinstance(element, DB.FamilyInstance):
connmgr = element.MEPModel.ConnectorManager
elif isinstance(element, DB.Plumbing.Pipe):
connmgr = element.ConnectorManager
if connmgr:
connelements = [
y.Owner
for x in connmgr.Connectors
for y in x.AllRefs
if x.IsConnected
and y.Owner.Id != element.Id
and y.ConnectorType != DB.ConnectorType.Logical
]
return connelements
``` | ### `get_fillpattern_element(fillpattern_name, fillpattern_target, doc=None)` Retrieves a FillPatternElement from the Revit document based on the given fill pattern name and target. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `fillpattern_name` | `str` | The name of the fill pattern to search for. | _required_ | | `fillpattern_target` | `FillPatternTarget` | The target type of the fill pattern (e.g., Drafting or Model). | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | DB.FillPatternElement: The FillPatternElement that matches the given name and target, or None if not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
``` | ```md-code__content
def get_fillpattern_element(fillpattern_name, fillpattern_target, doc=None):
"""
Retrieves a FillPatternElement from the Revit document based on the given fill pattern name and target.
Args:
fillpattern_name (str): The name of the fill pattern to search for.
fillpattern_target (DB.FillPatternTarget): The target type of the fill pattern (e.g., Drafting or Model).
doc (DB.Document, optional): The Revit document to search in. If not provided, defaults to DOCS.doc.
Returns:
DB.FillPatternElement: The FillPatternElement that matches the given name and target, or None if not found.
"""
doc = doc or DOCS.doc
existing_fp_elements = DB.FilteredElementCollector(doc).OfClass(
framework.get_type(DB.FillPatternElement)
)
for existing_fp_element in existing_fp_elements:
fillpattern = existing_fp_element.GetFillPattern()
if (
fillpattern_name == fillpattern.Name
and fillpattern_target == fillpattern.Target
):
return existing_fp_element
``` | ### `get_all_fillpattern_elements(fillpattern_target, doc=None)` Retrieves all fill pattern elements from the given document that match the specified fill pattern target. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `fillpattern_target` | `FillPatternTarget` | The target fill pattern to match. | _required_ | | `doc` | `Document` | The Revit document to search within. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of fill pattern elements that match the specified fill pattern target. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
``` | ```md-code__content
def get_all_fillpattern_elements(fillpattern_target, doc=None):
"""
Retrieves all fill pattern elements from the given document that match the specified fill pattern target.
Args:
fillpattern_target (DB.FillPatternTarget): The target fill pattern to match.
doc (DB.Document, optional): The Revit document to search within. If not provided, defaults to DOCS.doc.
Returns:
list: A list of fill pattern elements that match the specified fill pattern target.
"""
doc = doc or DOCS.doc
existing_fp_elements = DB.FilteredElementCollector(doc).OfClass(
framework.get_type(DB.FillPatternElement)
)
return [
x
for x in existing_fp_elements
if x.GetFillPattern().Target == fillpattern_target
]
``` | ### `get_fillpattern_from_element(element, background=True, doc=None)` Retrieves the fill pattern from a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element from which to retrieve the fill pattern. | _required_ | | `background` | `bool` | If True, retrieves the background fill pattern;
otherwise, retrieves the foreground fill pattern.
Defaults to True. | `True` | | `doc` | `Document` | The Revit document. If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | DB.FillPattern: The fill pattern of the specified element, or None if not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
``` | ```md-code__content
def get_fillpattern_from_element(element, background=True, doc=None):
"""
Retrieves the fill pattern from a given Revit element.
Args:
element (DB.Element): The Revit element from which to retrieve the fill pattern.
background (bool, optional): If True, retrieves the background fill pattern;
otherwise, retrieves the foreground fill pattern.
Defaults to True.
doc (DB.Document, optional): The Revit document. If not provided, defaults to DOCS.doc.
Returns:
DB.FillPattern: The fill pattern of the specified element, or None if not found.
"""
doc = doc or DOCS.doc
def get_fpm_from_frtype(etype):
fp_id = None
if HOST_APP.is_newer_than(2018):
# return requested fill pattern (background or foreground)
fp_id = (
etype.BackgroundPatternId if background else etype.ForegroundPatternId
)
else:
fp_id = etype.FillPatternId
if fp_id:
fillpat_element = doc.GetElement(fp_id)
if fillpat_element:
return fillpat_element.GetFillPattern()
if isinstance(element, DB.FilledRegion):
return get_fpm_from_frtype(doc.GetElement(element.GetTypeId()))
``` | ### `get_local_keynote_file(doc=None)` Retrieves the path to the local keynote file for the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document. If not provided, the default document (DOCS.doc) is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The user-visible path to the local keynote file if it is an external file reference, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
``` | ```md-code__content
def get_local_keynote_file(doc=None):
"""
Retrieves the path to the local keynote file for the given Revit document.
Args:
doc (DB.Document, optional): The Revit document. If not provided, the default document (DOCS.doc) is used.
Returns:
str: The user-visible path to the local keynote file if it is an external file reference, otherwise None.
"""
doc = doc or DOCS.doc
knote_table = DB.KeynoteTable.GetKeynoteTable(doc)
if knote_table.IsExternalFileReference():
knote_table_ref = knote_table.GetExternalFileReference()
return DB.ModelPathUtils.ConvertModelPathToUserVisiblePath(
knote_table_ref.GetAbsolutePath()
)
return None
``` | ### `get_external_keynote_file(doc=None)` Retrieves the path to the external keynote file associated with the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The in-session path to the external keynote file if it exists and has a valid display path, otherwise None. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
``` | ```md-code__content
def get_external_keynote_file(doc=None):
"""
Retrieves the path to the external keynote file associated with the given Revit document.
Args:
doc (DB.Document, optional): The Revit document to query. If not provided, defaults to DOCS.doc.
Returns:
str: The in-session path to the external keynote file if it exists and has a valid display path, otherwise None.
"""
doc = doc or DOCS.doc
knote_table = DB.KeynoteTable.GetKeynoteTable(doc)
if knote_table.RefersToExternalResourceReferences():
refs = knote_table.GetExternalResourceReferences()
if refs:
for ref_type, ref in dict(refs).items():
if ref.HasValidDisplayPath():
return ref.InSessionPath
return None
``` | ### `get_keynote_file(doc=None)` Retrieves the keynote file path for the given Revit document. If a local keynote file is available, it returns the local path. Otherwise, it returns the external keynote file path. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document. If not provided,
the default document (DOCS.doc) is used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The path to the keynote file. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
``` | ```md-code__content
def get_keynote_file(doc=None):
"""
Retrieves the keynote file path for the given Revit document.
If a local keynote file is available, it returns the local path.
Otherwise, it returns the external keynote file path.
Args:
doc (Document, optional): The Revit document. If not provided,
the default document (DOCS.doc) is used.
Returns:
str: The path to the keynote file.
"""
doc = doc or DOCS.doc
local_path = get_local_keynote_file(doc=doc)
if not local_path:
return get_external_keynote_file(doc=doc)
return local_path
``` | ### `get_used_keynotes(doc=None)` Retrieves all keynote tags used in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for keynote tags.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Type | Description | | --- | --- | | | List\[Element\]: A list of keynote tag elements found in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
``` | ```md-code__content
def get_used_keynotes(doc=None):
"""
Retrieves all keynote tags used in the given Revit document.
Args:
doc (Document, optional): The Revit document to search for keynote tags.
If not provided, defaults to DOCS.doc.
Returns:
List[Element]: A list of keynote tag elements found in the document.
"""
doc = doc or DOCS.doc
return (
DB.FilteredElementCollector(doc)
.OfCategory(DB.BuiltInCategory.OST_KeynoteTags)
.WhereElementIsNotElementType()
.ToElements()
)
``` | ### `get_visible_keynotes(view=None)` Retrieves all visible keynote tags in the specified Revit view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view from which to retrieve keynote tags. | `None` | Returns: | Type | Description | | --- | --- | | | list\[Autodesk.Revit.DB.Element\]: A list of keynote tag elements visible in the specified view. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
``` | ```md-code__content
def get_visible_keynotes(view=None):
"""
Retrieves all visible keynote tags in the specified Revit view.
Args:
view (Autodesk.Revit.DB.View): The Revit view from which to retrieve keynote tags.
Returns:
list[Autodesk.Revit.DB.Element]: A list of keynote tag elements visible in the specified view.
"""
doc = view.Document
return (
DB.FilteredElementCollector(doc, view.Id)
.OfCategory(DB.BuiltInCategory.OST_KeynoteTags)
.WhereElementIsNotElementType()
.ToElements()
)
``` | ### `get_available_keynotes(doc=None)` Retrieves the available keynotes from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve keynotes.
If not provided, the default document (DOCS.doc) will be used. | `None` | Returns: | Type | Description | | --- | --- | | | DB.KeyBasedTreeEntries: A collection of keynote entries from the keynote table. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
``` | ```md-code__content
def get_available_keynotes(doc=None):
"""
Retrieves the available keynotes from the given Revit document.
Args:
doc (DB.Document, optional): The Revit document from which to retrieve keynotes.
If not provided, the default document (DOCS.doc) will be used.
Returns:
DB.KeyBasedTreeEntries: A collection of keynote entries from the keynote table.
"""
doc = doc or DOCS.doc
knote_table = DB.KeynoteTable.GetKeynoteTable(doc)
return knote_table.GetKeyBasedTreeEntries()
``` | ### `get_available_keynotes_tree(doc=None)` Retrieves the available keynotes in a hierarchical tree structure. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve keynotes from.
If not provided, defaults to the current document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `dict` | | A dictionary representing the hierarchical structure of keynotes. | Raises: | Type | Description | | --- | --- | | `NotImplementedError` | This function is not yet implemented. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
``` | ```md-code__content
def get_available_keynotes_tree(doc=None):
"""
Retrieves the available keynotes in a hierarchical tree structure.
Args:
doc (Document, optional): The Revit document to retrieve keynotes from.
If not provided, defaults to the current document.
Returns:
dict: A dictionary representing the hierarchical structure of keynotes.
Raises:
NotImplementedError: This function is not yet implemented.
"""
doc = doc or DOCS.doc
knotes = get_available_keynotes(doc=doc)
# TODO: implement knotes tree
raise NotImplementedError()
``` | ### `is_placed(spatial_element)` Check if a spatial element (Room, Area, or Space) is placed and has a positive area. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `spatial_element` | `Element` | The spatial element to check. It can be an instance of
DB.Architecture.Room, DB.Area, or DB.Mechanical.Space. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the spatial element is placed and has an area greater than 0, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
``` | ```md-code__content
def is_placed(spatial_element):
"""
Check if a spatial element (Room, Area, or Space) is placed and has a positive area.
Args:
spatial_element (DB.Element): The spatial element to check. It can be an instance of
DB.Architecture.Room, DB.Area, or DB.Mechanical.Space.
Returns:
bool: True if the spatial element is placed and has an area greater than 0, False otherwise.
"""
return (
isinstance(
spatial_element, (DB.Architecture.Room, DB.Area, DB.Mechanical.Space)
)
and spatial_element.Area > 0
)
``` | ### `get_central_path(doc=None)` Returns the central model path of a Revit document if it is workshared. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `str` | | The user-visible path to the central model if the document is workshared. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
``` | ```md-code__content
def get_central_path(doc=None):
"""
Returns the central model path of a Revit document if it is workshared.
Args:
doc (Document, optional): The Revit document. If not provided, defaults to DOCS.doc.
Returns:
str: The user-visible path to the central model if the document is workshared.
"""
doc = doc or DOCS.doc
if doc.IsWorkshared:
model_path = doc.GetWorksharingCentralModelPath()
return DB.ModelPathUtils.ConvertModelPathToUserVisiblePath(model_path)
``` | ### `is_metric(doc=None)` Determines if the given Revit document uses the metric unit system. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to check. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the document uses the metric unit system, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
``` | ```md-code__content
def is_metric(doc=None):
"""
Determines if the given Revit document uses the metric unit system.
Args:
doc (Document, optional): The Revit document to check. If not provided,
the default document (DOCS.doc) will be used.
Returns:
bool: True if the document uses the metric unit system, False otherwise.
"""
doc = doc or DOCS.doc
return doc.DisplayUnitSystem == DB.DisplayUnit.METRIC
``` | ### `is_imperial(doc=None)` Checks if the given Revit document uses the imperial unit system. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to check. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the document uses the imperial unit system, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
``` | ```md-code__content
def is_imperial(doc=None):
"""
Checks if the given Revit document uses the imperial unit system.
Args:
doc (Document, optional): The Revit document to check. If not provided,
the default document (DOCS.doc) will be used.
Returns:
bool: True if the document uses the imperial unit system, False otherwise.
"""
doc = doc or DOCS.doc
return doc.DisplayUnitSystem == DB.DisplayUnit.IMPERIAL
``` | ### `get_view_sheetrefinfo(view)` Retrieves sheet reference information for a given view. This function checks if the view is placed on a sheet by looking at the 'Sheet Number' and 'Sheet Name' parameters. If the view is placed on a sheet, it returns the sheet number, sheet name, and detail number. If the view is not placed on a sheet, it checks the 'Referencing Sheet' and 'Referencing Detail' parameters to see if the view is referenced by another view on a sheet, and returns the corresponding information. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view object to retrieve sheet reference
information from. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `SheetRefInfo` | | An object containing the sheet number, sheet name, detail
number, and reference view ID if applicable. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
``` | ```md-code__content
def get_view_sheetrefinfo(view):
"""
Retrieves sheet reference information for a given view.
This function checks if the view is placed on a sheet by looking at the
'Sheet Number' and 'Sheet Name' parameters. If the view is placed on a
sheet, it returns the sheet number, sheet name, and detail number. If the
view is not placed on a sheet, it checks the 'Referencing Sheet' and
'Referencing Detail' parameters to see if the view is referenced by another
view on a sheet, and returns the corresponding information.
Args:
view (DB.View): The Revit view object to retrieve sheet reference
information from.
Returns:
SheetRefInfo: An object containing the sheet number, sheet name, detail
number, and reference view ID if applicable.
"""
sheet_num = view.Parameter[DB.BuiltInParameter.VIEWPORT_SHEET_NUMBER].AsString()
sheet_name = view.Parameter[DB.BuiltInParameter.VIEWPORT_SHEET_NAME].AsString()
detail_num = view.Parameter[DB.BuiltInParameter.VIEWPORT_DETAIL_NUMBER].AsString()
if sheet_num:
return SheetRefInfo(
sheet_num=sheet_num,
sheet_name=sheet_name,
detail_num=detail_num,
ref_viewid=None,
)
ref_sheet_num = view.Parameter[
DB.BuiltInParameter.VIEW_REFERENCING_SHEET
].AsString()
ref_sheet = get_sheet_by_number(ref_sheet_num)
ref_sheet_name = get_name(ref_sheet) if ref_sheet else ""
ref_detail_num = view.Parameter[
DB.BuiltInParameter.VIEW_REFERENCING_DETAIL
].AsString()
if ref_sheet_num:
return SheetRefInfo(
sheet_num=ref_sheet_num,
sheet_name=ref_sheet_name,
detail_num=ref_detail_num,
ref_viewid=get_view_by_sheetref(ref_sheet_num, ref_detail_num),
)
``` | ### `get_all_sheeted_views(doc=None, sheets=None)` Retrieves all view IDs that are placed on sheets in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. If not provided, defaults to DOCS.doc. | `None` | | `sheets` | `list` | A list of sheet elements to query. If not provided, defaults to all sheets in the document. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `set` | | A set of view IDs that are placed on the provided sheets. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
``` | ```md-code__content
def get_all_sheeted_views(doc=None, sheets=None):
"""
Retrieves all view IDs that are placed on sheets in the given Revit document.
Args:
doc (Document, optional): The Revit document to query. If not provided, defaults to DOCS.doc.
sheets (list, optional): A list of sheet elements to query. If not provided, defaults to all sheets in the document.
Returns:
set: A set of view IDs that are placed on the provided sheets.
"""
doc = doc or DOCS.doc
sheets = sheets or get_sheets(doc=doc)
all_sheeted_view_ids = set()
for sht in sheets:
vp_ids = [doc.GetElement(x).ViewId for x in sht.GetAllViewports()]
all_sheeted_view_ids.update(vp_ids)
return all_sheeted_view_ids
``` | ### `is_view_sheeted(view)` Checks if a given view is placed on a sheet. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the view is placed on a sheet, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
``` | ```md-code__content
def is_view_sheeted(view):
"""
Checks if a given view is placed on a sheet.
Args:
view (Autodesk.Revit.DB.View): The Revit view to check.
Returns:
bool: True if the view is placed on a sheet, False otherwise.
"""
return view.Id in get_all_sheeted_views(doc=view.Document)
``` | ### `can_refer_other_views(source_view)` Determines if the given source view can refer to other views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source_view` | | The view to check. Expected to be an instance of a Revit view class. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the source view is an instance of DB.ViewDrafting, DB.ViewPlan, or DB.ViewSection; otherwise, False. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
``` | ```md-code__content
def can_refer_other_views(source_view):
"""
Determines if the given source view can refer to other views.
Args:
source_view: The view to check. Expected to be an instance of a Revit view class.
Returns:
bool: True if the source view is an instance of DB.ViewDrafting, DB.ViewPlan, or DB.ViewSection; otherwise, False.
"""
return isinstance(source_view, (DB.ViewDrafting, DB.ViewPlan, DB.ViewSection))
``` | ### `is_referring_to(source_view, target_view)` Determines if the source view is referring to the target view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `source_view` | `View` | The view that may be referring to another view. | _required_ | | `target_view` | `View` | The view that is being checked if it is referred to by the source view. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the source view is referring to the target view, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
``` | ```md-code__content
def is_referring_to(source_view, target_view):
"""
Determines if the source view is referring to the target view.
Args:
source_view (Autodesk.Revit.DB.View): The view that may be referring to another view.
target_view (Autodesk.Revit.DB.View): The view that is being checked if it is referred to by the source view.
Returns:
bool: True if the source view is referring to the target view, False otherwise.
"""
doc = source_view.Document
target_viewname = get_name(target_view)
if can_refer_other_views(source_view):
for ref_elid in get_all_referencing_elements_in_view(source_view):
viewref_el = doc.GetElement(ref_elid)
targetview_param = viewref_el.Parameter[
DB.BuiltInParameter.REFERENCE_VIEWER_TARGET_VIEW
]
if targetview_param:
tvp_view = doc.GetElement(targetview_param.AsElementId())
if tvp_view and get_name(tvp_view) == target_viewname:
return True
else:
viewref_name = get_name(viewref_el)
if viewref_name == target_viewname:
return True
``` | ### `yield_referring_views(target_view, all_views=None)` Yields the IDs of views that refer to the target view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `target_view` | `View` | The view that other views may refer to. | _required_ | | `all_views` | `list[View]` | A list of all views to check. If not provided,
all views in the document of the target view will be used. | `None` | Yields: ElementId: The ID of a view that refers to the target view. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
``` | ```md-code__content
def yield_referring_views(target_view, all_views=None):
"""
Yields the IDs of views that refer to the target view.
Args:
target_view (View): The view that other views may refer to.
all_views (list[View], optional): A list of all views to check. If not provided,
all views in the document of the target view will be used.
Yields:
ElementId: The ID of a view that refers to the target view.
"""
all_views = all_views or get_all_views(doc=target_view.Document)
for view in all_views:
if is_referring_to(view, target_view):
yield view.Id
``` | ### `yield_referenced_views(doc=None, all_views=None)` Yields the IDs of views that have referring views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. Defaults to None, in which case the global DOCS.doc is used. | `None` | | `all_views` | `list` | A list of all views in the document. Defaults to None, in which case all views are retrieved using get\_all\_views(doc). | `None` | Yields: ElementId: The ID of a view that has referring views. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
``` | ```md-code__content
def yield_referenced_views(doc=None, all_views=None):
"""
Yields the IDs of views that have referring views.
Args:
doc (Document, optional): The Revit document to query. Defaults to None, in which case the global DOCS.doc is used.
all_views (list, optional): A list of all views in the document. Defaults to None, in which case all views are retrieved using get_all_views(doc).
Yields:
ElementId: The ID of a view that has referring views.
"""
doc = doc or DOCS.doc
all_views = all_views or get_all_views(doc=doc)
for view in all_views:
# if it has any referring views, yield
if next(yield_referring_views(view), None):
yield view.Id
``` | ### `yield_unreferenced_views(doc=None, all_views=None)` Yields the IDs of views in a Revit document that have no referring views. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to search for unreferenced views.
If not provided, defaults to DOCS.doc. | `None` | | `all_views` | `list` | A list of all views in the document.
If not provided, it will be retrieved using get\_all\_views(doc). | `None` | Yields: ElementId: The ID of each view that has no referring views. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
``` | ```md-code__content
def yield_unreferenced_views(doc=None, all_views=None):
"""
Yields the IDs of views in a Revit document that have no referring views.
Args:
doc (Document, optional): The Revit document to search for unreferenced views.
If not provided, defaults to DOCS.doc.
all_views (list, optional): A list of all views in the document.
If not provided, it will be retrieved using get_all_views(doc).
Yields:
ElementId: The ID of each view that has no referring views.
"""
doc = doc or DOCS.doc
all_views = all_views or get_all_views(doc=doc)
for view in all_views:
# if it has NO referring views, yield
if len(list(yield_referring_views(view))) == 0:
yield view.Id
``` | ### `get_line_categories(doc=None)` Retrieves the line categories from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve the line categories from.
If not provided, it defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `SubCategories` | | The subcategories of the line category in the Revit document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
``` | ```md-code__content
def get_line_categories(doc=None):
"""
Retrieves the line categories from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve the line categories from.
If not provided, it defaults to DOCS.doc.
Returns:
SubCategories: The subcategories of the line category in the Revit document.
"""
doc = doc or DOCS.doc
lines_cat = doc.Settings.Categories.get_Item(DB.BuiltInCategory.OST_Lines)
return lines_cat.SubCategories
``` | ### `get_line_styles(doc=None)` Retrieves the line styles from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to retrieve line styles from.
If None, the current document will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of GraphicsStyle objects representing the line styles in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
``` | ```md-code__content
def get_line_styles(doc=None):
"""
Retrieves the line styles from the given Revit document.
Args:
doc (Document, optional): The Revit document to retrieve line styles from.
If None, the current document will be used.
Returns:
list: A list of GraphicsStyle objects representing the line styles in the document.
"""
return [
x.GetGraphicsStyle(DB.GraphicsStyleType.Projection)
for x in get_line_categories(doc=doc)
]
``` | ### `get_history(target_element)` Retrieves the worksharing history of a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `target_element` | `Element` | The Revit element for which to retrieve the history. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `ElementHistory` | | An object containing the creator, owner, and last changed by information of the element. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
``` | ```md-code__content
def get_history(target_element):
"""
Retrieves the worksharing history of a given Revit element.
Args:
target_element (DB.Element): The Revit element for which to retrieve the history.
Returns:
ElementHistory: An object containing the creator, owner, and last changed by information of the element.
"""
doc = target_element.Document
if doc.IsWorkshared:
wti = DB.WorksharingUtils.GetWorksharingTooltipInfo(doc, target_element.Id)
return ElementHistory(
creator=wti.Creator, owner=wti.Owner, last_changed_by=wti.LastChangedBy
)
``` | ### `is_detail_curve(element)` Check if the given element is a detail curve. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The element to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the element is a detail curve, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
``` | ```md-code__content
def is_detail_curve(element):
"""
Check if the given element is a detail curve.
Args:
element: The element to check.
Returns:
bool: True if the element is a detail curve, False otherwise.
"""
return isinstance(element, DETAIL_CURVES)
``` | ### `is_model_curve(element)` Check if the given element is a model curve. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | | The element to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the element is a model curve, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
``` | ```md-code__content
def is_model_curve(element):
"""
Check if the given element is a model curve.
Args:
element: The element to check.
Returns:
bool: True if the element is a model curve, False otherwise.
"""
return isinstance(element, MODEL_CURVES)
``` | ### `is_sketch_curve(element)` Determines if the given Revit element is a sketch curve. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the element is a sketch curve, False otherwise. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
``` | ```md-code__content
def is_sketch_curve(element):
"""
Determines if the given Revit element is a sketch curve.
Args:
element (DB.Element): The Revit element to check.
Returns:
bool: True if the element is a sketch curve, False otherwise.
"""
if element.Category:
cid = element.Category.Id
return cid == DB.ElementId(DB.BuiltInCategory.OST_SketchLines)
``` | ### `get_all_schemas()` Retrieves all the schemas from the Extensible Storage in Revit. Returns: | Type | Description | | --- | --- | | | IList\[Schema\]: A list of all schemas available in the Extensible Storage. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2733
2734
2735
2736
2737
2738
2739
2740
``` | ```md-code__content
def get_all_schemas():
"""
Retrieves all the schemas from the Extensible Storage in Revit.
Returns:
IList[Schema]: A list of all schemas available in the Extensible Storage.
"""
return DB.ExtensibleStorage.Schema.ListSchemas()
``` | ### `get_schema_field_values(element, schema)` Retrieves the values of fields from a given schema for a specified Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element from which to retrieve the schema field values. | _required_ | | `schema` | `Schema` | The schema that defines the fields to retrieve. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `dict` | | A dictionary where the keys are field names and the values are the corresponding field values. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
``` | ```md-code__content
def get_schema_field_values(element, schema):
"""
Retrieves the values of fields from a given schema for a specified Revit element.
Args:
element (DB.Element): The Revit element from which to retrieve the schema field values.
schema (DB.ExtensibleStorage.Schema): The schema that defines the fields to retrieve.
Returns:
dict: A dictionary where the keys are field names and the values are the corresponding field values.
"""
field_values = {}
entity = element.GetEntity(schema)
if entity:
for field in schema.ListFields():
field_type = field.ValueType
if field.ContainerType == DB.ExtensibleStorage.ContainerType.Array:
field_type = framework.IList[field.ValueType]
elif field.ContainerType == DB.ExtensibleStorage.ContainerType.Map:
field_type = framework.IDictionary[field.KeyType, field.ValueType]
try:
value = entity.Get[field_type](
field.FieldName, DB.DisplayUnitType.DUT_UNDEFINED
)
except:
value = None
field_values[field.FieldName] = value
return field_values
``` | ### `get_family_type(type_name, family_doc)` Retrieves a family type from a Revit family document by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `type_name` | `str` | The name of the family type to retrieve. | _required_ | | `family_doc` | `Document` | The Revit family document to search in. If None, the default document (DOCS.doc) is used. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `FamilyType` | | The family type with the specified name. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the provided document is not a family document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
``` | ```md-code__content
def get_family_type(type_name, family_doc):
"""
Retrieves a family type from a Revit family document by its name.
Args:
type_name (str): The name of the family type to retrieve.
family_doc (Document): The Revit family document to search in. If None, the default document (DOCS.doc) is used.
Returns:
FamilyType: The family type with the specified name.
Raises:
PyRevitException: If the provided document is not a family document.
"""
family_doc = family_doc or DOCS.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")
``` | ### `get_family_parameter(param_name, family_doc)` Retrieves a family parameter from a Revit family document by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `param_name` | `str` | The name of the parameter to retrieve. | _required_ | | `family_doc` | `Document` | The Revit family document to search in. If None, defaults to DOCS.doc. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `FamilyParameter` | | The family parameter with the specified name. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the provided document is not a family document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
``` | ```md-code__content
def get_family_parameter(param_name, family_doc):
"""
Retrieves a family parameter from a Revit family document by its name.
Args:
param_name (str): The name of the parameter to retrieve.
family_doc (Document): The Revit family document to search in. If None, defaults to DOCS.doc.
Returns:
FamilyParameter: The family parameter with the specified name.
Raises:
PyRevitException: If the provided document is not a family document.
"""
family_doc = family_doc or DOCS.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")
``` | ### `get_family_parameters(family_doc)` Retrieves the parameters of a Revit family document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_doc` | | The Revit family document from which to retrieve parameters.
If None, the default document (DOCS.doc) will be used. | _required_ | Returns: | Type | Description | | --- | --- | | | A collection of family parameters from the specified family document. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the provided document is not a family document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
``` | ```md-code__content
def get_family_parameters(family_doc):
"""
Retrieves the parameters of a Revit family document.
Args:
family_doc: The Revit family document from which to retrieve parameters.
If None, the default document (DOCS.doc) will be used.
Returns:
A collection of family parameters from the specified family document.
Raises:
PyRevitException: If the provided document is not a family document.
"""
family_doc = family_doc or DOCS.doc
if family_doc.IsFamilyDocument:
return family_doc.FamilyManager.GetParameters()
else:
raise PyRevitException("Document is not a family")
``` | ### `get_family_label_parameters(family_doc)` Retrieves the set of family label parameters from a given Revit family document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `family_doc` | `Document` | The Revit family document to retrieve label parameters from.
If None, the default document (DOCS.doc) is used. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `set` | | A set of family label parameters (DB.FamilyParameter) found in the document. | Raises: | Type | Description | | --- | --- | | `PyRevitException` | If the provided document is not a family document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
``` | ```md-code__content
def get_family_label_parameters(family_doc):
"""
Retrieves the set of family label parameters from a given Revit family document.
Args:
family_doc (DB.Document): The Revit family document to retrieve label parameters from.
If None, the default document (DOCS.doc) is used.
Returns:
set: A set of family label parameters (DB.FamilyParameter) found in the document.
Raises:
PyRevitException: If the provided document is not a family document.
"""
family_doc = family_doc or DOCS.doc
if family_doc.IsFamilyDocument:
dims = (
DB.FilteredElementCollector(family_doc)
.OfClass(DB.Dimension)
.WhereElementIsNotElementType()
)
label_params = set()
for dim in dims:
try:
# throws exception when dimension can not be labeled
if isinstance(dim.FamilyLabel, DB.FamilyParameter):
label_params.add(dim.FamilyLabel)
except Exception:
pass
return label_params
else:
raise PyRevitException("Document is not a family")
``` | ### `get_door_rooms(door)` Get from/to rooms associated with given door element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `door` | `FamilyInstance` | door instance | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `tuple` | `(Room, Room)` | from/to rooms | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
``` | ```md-code__content
def get_door_rooms(door):
"""Get from/to rooms associated with given door element.
Args:
door (DB.FamilyInstance): door instance
Returns:
tuple(DB.Architecture.Room, DB.Architecture.Room): from/to rooms
"""
door_phase = door.Document.GetElement(door.CreatedPhaseId)
return (door.FromRoom[door_phase], door.ToRoom[door_phase])
``` | ### `get_doors(elements=None, doc=None, room_id=None)` Get all doors in active or given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `elements` | `list[Element]` | find rooms in given elements instead | `None` | | `doc` | `Document` | target document; default is active document | `None` | | `room_id` | `ElementId` | only doors associated with given room | `None` | Returns: | Type | Description | | --- | --- | | `list[Element]` | room instances | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
``` | ```md-code__content
def get_doors(elements=None, doc=None, room_id=None):
"""Get all doors in active or given document.
Args:
elements (list[DB.Element]): find rooms in given elements instead
doc (DB.Document): target document; default is active document
room_id (DB.ElementId): only doors associated with given room
Returns:
(list[DB.Element]): room instances
"""
doc = doc or DOCS.doc
all_doors = get_elements_by_categories(
[DB.BuiltInCategory.OST_Doors], elements=elements, doc=doc
)
if room_id:
room_doors = []
for door in all_doors:
from_room, to_room = get_door_rooms(door)
if (from_room and from_room.Id == room_id) or (
to_room and to_room.Id == room_id
):
room_doors.append(door)
return room_doors
else:
return list(all_doors)
``` | ### `get_all_print_settings(doc=None)` Retrieves all print settings from the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document from which to retrieve print settings.
If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of print settings elements from the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
``` | ```md-code__content
def get_all_print_settings(doc=None):
"""
Retrieves all print settings from the given Revit document.
Args:
doc (Document, optional): The Revit document from which to retrieve print settings.
If not provided, defaults to DOCS.doc.
Returns:
list: A list of print settings elements from the document.
"""
doc = doc or DOCS.doc
return [doc.GetElement(x) for x in doc.GetPrintSettingIds()]
``` | ### `get_used_paper_sizes(doc=None)` Retrieves a list of used paper sizes from the print settings in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | `Document` | The Revit document to query. If not provided, defaults to DOCS.doc. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of paper sizes used in the print settings of the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
``` | ```md-code__content
def get_used_paper_sizes(doc=None):
"""
Retrieves a list of used paper sizes from the print settings in the given Revit document.
Args:
doc (Document, optional): The Revit document to query. If not provided, defaults to DOCS.doc.
Returns:
list: A list of paper sizes used in the print settings of the document.
"""
doc = doc or DOCS.doc
return [x.PrintParameters.PaperSize for x in get_all_print_settings(doc=doc)]
``` | ### `find_paper_size_by_name(paper_size_name, doc=None)` Finds and returns a paper size object by its name. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `paper_size_name` | `str` | The name of the paper size to find. | _required_ | | `doc` | `Document` | The Revit document to search in. If not provided,
the default document (DOCS.doc) will be used. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `PaperSize` | | The paper size object that matches the given name, or None if not found. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
``` | ```md-code__content
def find_paper_size_by_name(paper_size_name, doc=None):
"""
Finds and returns a paper size object by its name.
Args:
paper_size_name (str): The name of the paper size to find.
doc (Document, optional): The Revit document to search in. If not provided,
the default document (DOCS.doc) will be used.
Returns:
PaperSize: The paper size object that matches the given name, or None if not found.
"""
doc = doc or DOCS.doc
paper_size_name = paper_size_name.lower()
for psize in doc.PrintManager.PaperSizes:
if psize.Name.lower() == paper_size_name:
return psize
``` | ### `find_paper_sizes_by_dims(printer_name, paper_width, paper_height, doc=None)` Finds paper sizes by dimensions for a given printer. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `printer_name` | `str` | The name of the printer. | _required_ | | `paper_width` | `float` | The width of the paper in inches. | _required_ | | `paper_height` | `float` | The height of the paper in inches. | _required_ | | `doc` | `optional` | The document context. Defaults to None. | `None` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of matching paper sizes. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
``` | ```md-code__content
def find_paper_sizes_by_dims(printer_name, paper_width, paper_height, doc=None):
"""
Finds paper sizes by dimensions for a given printer.
Args:
printer_name (str): The name of the printer.
paper_width (float): The width of the paper in inches.
paper_height (float): The height of the paper in inches.
doc (optional): The document context. Defaults to None.
Returns:
list: A list of matching paper sizes.
"""
doc = doc or DOCS.doc
paper_sizes = []
system_paper_sizes = coreutils.get_paper_sizes(printer_name)
mlogger.debug("looking for paper size W:%s H:%s", paper_width, paper_height)
mlogger.debug(
"system paper sizes: %s -> %s",
printer_name,
[x.PaperName for x in system_paper_sizes],
)
for sys_psize in system_paper_sizes:
sys_pname = sys_psize.PaperName
sys_pwidth = int(sys_psize.Width / 100.00)
sys_pheight = int(sys_psize.Height / 100.00)
wxd = paper_width == sys_pwidth and paper_height == sys_pheight
dxw = paper_width == sys_pheight and paper_height == sys_pwidth
mlogger.debug(
'%s "%s" W:%s H:%s',
"✓" if wxd or dxw else " ",
sys_pname,
sys_pwidth,
sys_pheight,
)
if wxd or dxw:
psize = find_paper_size_by_name(sys_pname)
if psize:
paper_sizes.append(psize)
mlogger.debug("found matching paper: %s", psize.Name)
return paper_sizes
``` | ### `get_titleblock_print_settings(tblock, printer_name, doc_psettings)` Retrieves the print settings for a given title block that match the specified printer and document print settings. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `tblock` | `FamilyInstance` | The title block instance. | _required_ | | `printer_name` | `str` | The name of the printer. | _required_ | | `doc_psettings` | `list[PrintSetting]` | A list of document print settings. | _required_ | Returns: | Type | Description | | --- | --- | | | list\[DB.PrintSetting\]: A sorted list of print settings that match the title block size and orientation. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
``` | ```md-code__content
def get_titleblock_print_settings(tblock, printer_name, doc_psettings):
"""
Retrieves the print settings for a given title block that match the specified printer and document print settings.
Args:
tblock (DB.FamilyInstance): The title block instance.
printer_name (str): The name of the printer.
doc_psettings (list[DB.PrintSetting]): A list of document print settings.
Returns:
list[DB.PrintSetting]: A sorted list of print settings that match the title block size and orientation.
"""
doc = tblock.Document
page_width_param = tblock.Parameter[DB.BuiltInParameter.SHEET_WIDTH]
page_height_param = tblock.Parameter[DB.BuiltInParameter.SHEET_HEIGHT]
page_width = int(round(page_width_param.AsDouble() * 12.0))
page_height = int(round(page_height_param.AsDouble() * 12.0))
tform = tblock.GetTotalTransform()
is_portrait = (page_width < page_height) or (int(tform.BasisX.Y) == -1)
paper_sizes = find_paper_sizes_by_dims(
printer_name, page_width, page_height, doc=doc
)
paper_size_names = [x.Name for x in paper_sizes]
page_orient = (
DB.PageOrientationType.Portrait
if is_portrait
else DB.PageOrientationType.Landscape
)
all_tblock_psettings = set()
for doc_psetting in doc_psettings:
try:
pparams = doc_psetting.PrintParameters
if (
pparams.PaperSize
and pparams.PaperSize.Name in paper_size_names
and (pparams.ZoomType == DB.ZoomType.Zoom and pparams.Zoom == 100)
and pparams.PageOrientation == page_orient
):
all_tblock_psettings.add(doc_psetting)
except Exception:
mlogger.debug("incompatible psettings: %s", doc_psetting.Name)
return sorted(all_tblock_psettings, key=lambda x: x.Name)
``` | ### `get_crop_region(view)` Takes crop region of a view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | view to get crop region from | _required_ | Returns: | Type | Description | | --- | --- | | `list[CurveLoop]` | list of curve loops | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
``` | ```md-code__content
def get_crop_region(view):
"""Takes crop region of a view.
Args:
view (DB.View): view to get crop region from
Returns:
(list[DB.CurveLoop]): list of curve loops
"""
crsm = view.GetCropRegionShapeManager()
if HOST_APP.is_newer_than(2015):
crsm_valid = crsm.CanHaveShape
else:
crsm_valid = crsm.Valid
if crsm_valid:
if HOST_APP.is_newer_than(2015):
curve_loops = list(crsm.GetCropShape())
else:
curve_loops = [crsm.GetCropRegionShape()]
if curve_loops:
return curve_loops
``` | ### `is_cropable_view(view)` Determines if a given Revit view can be cropped. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view to check. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `bool` | | True if the view can be cropped, False otherwise. | Notes A view is considered cropable if it is not an instance of DB.ViewSheet or DB.TableView, and its ViewType is not Legend or DraftingView. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
``` | ```md-code__content
def is_cropable_view(view):
"""
Determines if a given Revit view can be cropped.
Args:
view (DB.View): The Revit view to check.
Returns:
bool: True if the view can be cropped, False otherwise.
Notes:
A view is considered cropable if it is not an instance of DB.ViewSheet or DB.TableView,
and its ViewType is not Legend or DraftingView.
"""
return not isinstance(view, (DB.ViewSheet, DB.TableView)) and view.ViewType not in (
DB.ViewType.Legend,
DB.ViewType.DraftingView,
)
``` | ### `get_view_filters(view)` Retrieves the filters applied to a given Revit view. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `view` | `View` | The Revit view from which to retrieve the filters. | _required_ | Returns: | Type | Description | | --- | --- | | | list\[Autodesk.Revit.DB.Element\]: A list of filter elements applied to the view. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
``` | ```md-code__content
def get_view_filters(view):
"""
Retrieves the filters applied to a given Revit view.
Args:
view (Autodesk.Revit.DB.View): The Revit view from which to retrieve the filters.
Returns:
list[Autodesk.Revit.DB.Element]: A list of filter elements applied to the view.
"""
view_filters = []
for filter_id in view.GetFilters():
filter_element = view.Document.GetElement(filter_id)
view_filters.append(filter_element)
return view_filters
``` | ### `get_element_workset(element)` Retrieves the workset of a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element for which to retrieve the workset. | _required_ | Returns: | Type | Description | | --- | --- | | | DB.Workset: The workset to which the element belongs, or None if the element's workset ID is invalid. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
``` | ```md-code__content
def get_element_workset(element):
"""
Retrieves the workset of a given Revit element.
Args:
element (DB.Element): The Revit element for which to retrieve the workset.
Returns:
DB.Workset: The workset to which the element belongs, or None if the element's workset ID is invalid.
"""
doc = element.Document
workset_table = doc.GetWorksetTable()
if element.WorksetId != DB.WorksetId.InvalidWorksetId:
return workset_table.GetWorkset(element.WorksetId)
``` | ### `get_geometry(element, include_invisible=False, compute_references=False)` Retrieves the geometry of a given Revit element. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `element` | `Element` | The Revit element from which to retrieve geometry. | _required_ | | `include_invisible` | `bool` | If True, includes non-visible objects in the geometry. Defaults to False. | `False` | | `compute_references` | `bool` | If True, computes references for the geometry objects. Defaults to False. | `False` | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of geometry objects associated with the element. If the element has no geometry, returns None. | Raises: | Type | Description | | --- | --- | | `TypeError` | If the element's geometry cannot be retrieved. | Notes - If the geometry object is an instance of DB.GeometryInstance, its instance geometry is retrieved and added to the list. - Logs a debug message if the element has no geometry. Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
``` | ```md-code__content
def get_geometry(element, include_invisible=False, compute_references=False):
"""
Retrieves the geometry of a given Revit element.
Args:
element (DB.Element): The Revit element from which to retrieve geometry.
include_invisible (bool, optional): If True, includes non-visible objects in the geometry. Defaults to False.
compute_references (bool, optional): If True, computes references for the geometry objects. Defaults to False.
Returns:
list: A list of geometry objects associated with the element. If the element has no geometry, returns None.
Raises:
TypeError: If the element's geometry cannot be retrieved.
Notes:
- If the geometry object is an instance of DB.GeometryInstance, its instance geometry is retrieved and added to the list.
- Logs a debug message if the element has no geometry.
"""
geom_opts = DB.Options()
geom_opts.IncludeNonVisibleObjects = include_invisible
geom_opts.ComputeReferences = compute_references
geom_objs = []
try:
for gobj in element.Geometry[geom_opts]:
if isinstance(gobj, DB.GeometryInstance):
inst_geom = gobj.GetInstanceGeometry()
geom_objs.extend(list(inst_geom))
else:
geom_objs.append(gobj)
return geom_objs
except TypeError:
get_elementid_value = get_elementid_value_func()
mlogger.debug("element %s has no geometry", get_elementid_value(element.Id))
return
``` | ### `get_array_group_ids(doc=None)` Collects and returns the IDs of all array groups in the given document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `document` | `Document` | The Revit document to search for array groups. | _required_ | Returns: | Name | Type | Description | | --- | --- | --- | | `list` | | A list of element IDs representing the array groups. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
``` | ```md-code__content
def get_array_group_ids(doc=None):
"""
Collects and returns the IDs of all array groups in the given document.
Args:
document (DB.Document): The Revit document to search for array groups.
Returns:
list: A list of element IDs representing the array groups.
"""
array_list = DB.FilteredElementCollector(doc or DOCS.doc).OfCategory(
DB.BuiltInCategory.OST_IOSArrays
)
arrays_groups = []
for ar in array_list:
arrays_groups.extend(ar.GetOriginalMemberIds())
arrays_groups.extend(ar.GetCopiedMemberIds())
return set(arrays_groups)
``` | ### `get_array_group_ids_types(doc=None)` Retrieves the unique types of array groups in the given Revit document. Parameters: | Name | Type | Description | Default | | --- | --- | --- | --- | | `doc` | | The Revit document from which to collect array group types. | `None` | Returns: | Type | Description | | --- | --- | | | A set of unique array group type IDs present in the document. | Source code in `pyrevitlib/pyrevit/revit/db/query.py` | | | | --- | --- | | ```
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
``` | ```md-code__content
def get_array_group_ids_types(doc=None):
"""
Retrieves the unique types of array groups in the given Revit document.
Args:
doc: The Revit document from which to collect array group types.
Returns:
A set of unique array group type IDs present in the document.
"""
arrays_groups = get_array_group_ids(doc or DOCS.doc)
return {doc.GetElement(ar).GetTypeId() for ar in arrays_groups}
``` | Back to top