Skip to content

forms

pyrevit.forms facade.

Imports the engine-specific forms backend for the active Python engine.

Attributes

HOST_APP = _HostApplication() module-attribute

EXEC_PARAMS = _ExecutorParams() module-attribute

DOCS = _DocsGetter() module-attribute

BIN_DIR = op.join(ROOT_BIN_DIR, DOTNET_RUNTIME_ID) module-attribute

safe_strtype = str module-attribute

user_config = PyRevitConfig(cfg_file_path=CONFIG_FILE, config_type=CONFIG_TYPE) module-attribute

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', 'isunit', 'storagetype']) 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

isunit bool

true if its ForgeTypeId is measurable

storagetype Storagetype

String, Integer, Double or ElementId

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.

reactive(getter)

Bases: property

Decorator for WPF bound properties.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def __init__(self, window):
    self._window = window

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:

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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
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)

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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@checked.setter
def checked(self, value):
    self.state = value

GetValueWindow(context, title, width, height, **kwargs)

Bases: TemplateUserInputWindow

Standard form to get simple values from user.

Examples:

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/_ipy.py
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
    )
    if title:
        self.Title = title
    else:
        try:
            localized_title = self.get_locale_string(self.default_title_key)
        except System.Windows.ResourceReferenceKeyNotFoundException:
            localized_title = None
        self.Title = localized_title if isinstance(localized_title, str) else "User Input"
    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'.

default_title_key = 'pyRevit.DefaultWindowTitle' class-attribute instance-attribute
Title = title 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/_ipy.py
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))
        if getattr(self, '_pending_resource_merge', None):
            self.merge_resource_dict(self._pending_resource_merge)
            self._pending_resource_merge = None
    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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def hide(self):
    """Hide window."""
    self.Hide()
show(context, title=None, 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

None
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/_ipy.py
@classmethod
def show(
    cls,
    context,  # pylint: disable=W0221
    title=None,
    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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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:
            selected = self.datePicker.SelectedDate
            self.response = datetime.datetime(
                selected.Year,
                selected.Month,
                selected.Day
            )
        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/_ipy.py
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/_ipy.py
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))
        if getattr(self, '_pending_resource_merge', None):
            self.merge_resource_dict(self._pending_resource_merge)
            self._pending_resource_merge = None
    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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def hide(self):
    """Hide window."""
    self.Hide()
show(modal=False)

Show window.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
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/_ipy.py
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:

with WarningBar(title='my warning'):
   # do stuff

Initialize user prompt window.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
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))
        if getattr(self, '_pending_resource_merge', None):
            self.merge_resource_dict(self._pending_resource_merge)
            self._pending_resource_merge = None
    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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def hide(self):
    """Hide window."""
    self.Hide()
show(modal=False)

Show window.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
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/_ipy.py
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

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:

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/_ipy.py
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/_ipy.py
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))
        if getattr(self, '_pending_resource_merge', None):
            self.merge_resource_dict(self._pending_resource_merge)
            self._pending_resource_merge = None
    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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def hide(self):
    """Hide window."""
    self.Hide()
show_dialog()

Show modal window.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@checked.setter
def checked(self, value):
    self.state = value

FamilyParamOption(fparam, builtin=False, labeled=False, associated=False)

Bases: TemplateListItem

Level wrapper for :func:select_family_parameters.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
def __init__(self, fparam, builtin=False, labeled=False, associated=False):
    super(FamilyParamOption, self).__init__(fparam)
    self.isbuiltin = builtin
    self.islabeled = labeled
    self.isassociated = associated

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
isassociated = associated 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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
def unwrap(self):
    """Unwrap and return wrapped object."""
    return self.item
checked(value)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
@checked.setter
def checked(self, value):
    self.state = value

WPFWindow(*args, **kwargs)

Bases: _NotSupportedBase

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def __init__(self, *args, **kwargs):
    _raise_not_supported(self._feature_name)

TemplateUserInputWindow(*args, **kwargs)

Bases: WPFWindow

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def __init__(self, *args, **kwargs):
    _raise_not_supported(self._feature_name)

Functions

show(*args, **kwargs) classmethod
Source code in pyrevitlib/pyrevit/forms/_cpy.py
@classmethod
def show(cls, *args, **kwargs):
    cls._raise("show")

SelectFromList(*args, **kwargs)

Bases: TemplateUserInputWindow

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def __init__(self, *args, **kwargs):
    _raise_not_supported(self._feature_name)

Functions

show(*args, **kwargs) classmethod
Source code in pyrevitlib/pyrevit/forms/_cpy.py
@classmethod
def show(cls, *args, **kwargs):
    cls._raise("show")

CommandSwitchWindow(*args, **kwargs)

Bases: TemplateUserInputWindow

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def __init__(self, *args, **kwargs):
    _raise_not_supported(self._feature_name)

Functions

show(*args, **kwargs) classmethod
Source code in pyrevitlib/pyrevit/forms/_cpy.py
@classmethod
def show(cls, *args, **kwargs):
    cls._raise("show")

ProgressBar(*args, **kwargs)

Bases: _NotSupportedBase

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def __init__(self, *args, **kwargs):
    _raise_not_supported(self._feature_name)

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:

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) for x in self.revit_sheet.GetAdditionalRevisionIds()}
Source code in pyrevitlib/pyrevit/compat.py
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) for x in self.revit_sheet.GetAdditionalRevisionIds()}
        ```
    """
    attr = "Value" if _get_revit_version() > 2023 else "IntegerValue"
    def from_elementid(item):
        return getattr(item, attr)
    return from_elementid

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:

get_logger('my command')

Source code in pyrevitlib/pyrevit/coreutils/logger.py
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')
        ```
        <LoggerWrapper ...>
    """
    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

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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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:

from pyrevit import forms
forms.select_revisions()
[<Autodesk.Revit.DB.Revision object>,
 <Autodesk.Revit.DB.Revision object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.Revision object>,
         <Autodesk.Revit.DB.Revision object>]
        ```
    """
    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:

from pyrevit import forms
forms.select_sheets()
[<Autodesk.Revit.DB.ViewSheet object>,
 <Autodesk.Revit.DB.ViewSheet object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.ViewSheet object>,
         <Autodesk.Revit.DB.ViewSheet object>]
        ```
    """
    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
        )
        if sheetset.Name == 'All Sheets':
            all_ops["[" + sheetset.Name + "]"] = sheetset_ops
        else:
            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:

from pyrevit import forms
forms.select_views()
[<Autodesk.Revit.DB.View object>,
 <Autodesk.Revit.DB.View object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.View object>,
         <Autodesk.Revit.DB.View object>]
        ```
    """
    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:

from pyrevit import forms
forms.select_levels()
[<Autodesk.Revit.DB.Level object>,
 <Autodesk.Revit.DB.Level object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.Level object>,
         <Autodesk.Revit.DB.Level object>]
        ```
    """
    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:

from pyrevit import forms
forms.select_viewtemplates()
[<Autodesk.Revit.DB.View object>,
 <Autodesk.Revit.DB.View object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.View object>,
         <Autodesk.Revit.DB.View object>]
        ```
    """
    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:

from pyrevit import forms
forms.select_schedules()
[<Autodesk.Revit.DB.ViewSchedule object>,
 <Autodesk.Revit.DB.ViewSchedule object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.ViewSchedule object>,
         <Autodesk.Revit.DB.ViewSchedule object>]
        ```
    """
    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:

from pyrevit import forms
forms.select_open_docs()
[<Autodesk.Revit.DB.Document object>,
 <Autodesk.Revit.DB.Document object>]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        [<Autodesk.Revit.DB.Document object>,
         <Autodesk.Revit.DB.Document object>]
        ```
    """
    # 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:

from pyrevit import forms
forms.select_titleblocks()
<Autodesk.Revit.DB.ElementId object>
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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()
        <Autodesk.Revit.DB.ElementId object>
        ```
    """
    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:

from pyrevit import forms
forms.select_swatch(title="Select Text Color")
<RGB #CD8800>
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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")
        <RGB #CD8800>
        ```
    """
    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:

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/_ipy.py
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:

forms.select_parameter(
    src_element,
    title='Select Parameters',
    multiple=True,
    include_instance=True,
    include_type=True
)
[<ParamDef >, <ParamDef >]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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
        )
        [<ParamDef >, <ParamDef >]
        ```
    """
    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,
                    isunit=(
                        DB.UnitUtils.IsMeasurableSpec(x.Definition.GetDataType())
                        if HOST_APP.is_newer_than(2022, True)
                        else False
                    ),
                    storagetype=x.StorageType,
                )
                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,
                        isunit=(
                            DB.UnitUtils.IsMeasurableSpec(x.Definition.GetDataType())
                            if HOST_APP.is_newer_than(2022, True)
                            else False
                        ),
                        storagetype=x.StorageType,
                    )
                    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, include_associated=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
include_associated bool

list parameters associated to others

True

Returns:

Type Description
list[FamilyParameter]

list of family parameter objects

Examples:

forms.select_family_parameters(
    family_doc,
    title='Select Parameters',
    multiple=True,
    include_instance=True,
    include_type=True
)
[<DB.FamilyParameter >, <DB.FamilyParameter >]
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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,
    include_associated=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
        include_associated (bool, optional):
            list parameters associated to others

    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
        )
        [<DB.FamilyParameter >, <DB.FamilyParameter >]
        ```
    """
    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

        associated_to_others = not family_param.AssociatedParameters.IsEmpty
        if not include_associated and associated_to_others:
            continue

        param_defs.append(
            FamilyParamOption(
                family_param,
                builtin=get_elementid_value(family_param.Id) < 0,
                labeled=family_param.Id in label_param_ids,
                associated=associated_to_others,
            )
        )

    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],
            "Associated to Others": [x for x in param_defs if x.isassociated],
        },
        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:

from pyrevit import forms
forms.alert('Are you sure?',
            sub_msg='<a href=\"https://discourse.pyrevitlabs.io/ \">Click here if you are not sure and want to go to the pyRevit Forum</a>',
            ok=False, yes=True, no=True, exitscript=True)
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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='<a href=\"https://discourse.pyrevitlabs.io/ \">Click here if you are not sure and want to go to the pyRevit Forum</a>',
                    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:

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/_ipy.py
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)

result_item_result_clicked(sender, e, debug=False)

Callback for a result item click event.

Source code in pyrevitlib/pyrevit/forms/_ipy.py
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

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:

from pyrevit import forms
forms.save_file(file_ext='csv')
r'C:\output\somefile.csv'
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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/_ipy.py
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:

from pyrevit import forms
forms.check_familydoc(doc=revit.doc, family_cat='Data Devices')
True
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

from pyrevit import forms
forms.check_modeldoc(doc=revit.doc)
True
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

from pyrevit import forms
forms.check_modelview(view=revit.active_view)
True
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

from pyrevit import forms
forms.check_viewtype(revit.active_view, DB.ViewType.DrawingSheet)
True
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

from pyrevit import forms
forms.check_graphicalview(revit.active_view)
True
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

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/_ipy.py
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_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/_ipy.py
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:

forms.ask_for_color()
'#ff808080'
Source code in pyrevitlib/pyrevit/forms/_ipy.py
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:

forms.inform_wip()
Source code in pyrevitlib/pyrevit/forms/_ipy.py
def inform_wip():
    """Show work-in-progress prompt to user and exit script.

    Examples:
        ```python
        forms.inform_wip()
        ```
    """
    alert("Work in progress.", exitscript=True)

pick_folder(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def pick_folder(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.pick_folder")

show_balloon(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def show_balloon(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.show_balloon")

pick_file(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def pick_file(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.pick_file")

ask_for_string(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def ask_for_string(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.ask_for_string")

ask_for_unique_string(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def ask_for_unique_string(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.ask_for_unique_string")

ask_for_one_item(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def ask_for_one_item(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.ask_for_one_item")

ask_for_date(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def ask_for_date(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.ask_for_date")

ask_for_number_slider(*args, **kwargs)

Source code in pyrevitlib/pyrevit/forms/_cpy.py
def ask_for_number_slider(*args, **kwargs):
    _raise_not_supported("pyrevit.forms.ask_for_number_slider")