', 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 = '
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('%s>' % 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