def remove_keynote(self, sender, args): # TODO: ask user which category to move the subkeynotes or delete? selected_keynote = self.selected_keynote if selected_keynote: if selected_keynote.children: forms.alert("Keynote \"%s\" has sub-keynotes. " "Delete all its sub-keynotes first." % selected_keynote.key) elif selected_keynote.used: forms.alert("Keynote \"%s\" is used in the model. " "Can not delete." % selected_keynote.key) else: if forms.alert("Are you sure you want to delete keynote " "\"%s\"?" % selected_keynote.key, yes=True, no=True): try: kdb.remove_keynote(self._conn, selected_keynote.key) except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: forms.alert(str(ex)) finally: self._update_ktree_knotes()
def remove_category(self, sender, args): # TODO: ask user which category to move the subkeynotes or delete? selected_category = self.selected_category if selected_category: if self.current_keynotes: forms.alert("Category \"%s\" is not empty. " "Delete all its keynotes first." % selected_category.key) elif selected_category.used: forms.alert("Category \"%s\" is used in the model. " "Can not delete." % selected_category.key) else: if forms.alert("Are you sure you want to delete category " "\"%s\"?" % selected_category.key, yes=True, no=True): try: kdb.remove_category(self._conn, selected_category.key) except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: forms.alert(str(ex)) finally: self._update_ktree(active_catkey=self._allcat)
def delete_click(self, sender, e): """Delete definitions from definition file""" definition_file = self.definition_file if not definition_file: self.invalid_definition_file() return confirmed = alert( "Are you sur you want to delete followinge parameters : \n{}". format("\n".join( [item.name for item in self.datagrid.SelectedItems])), "Delete parameters ?", yes=True, no=True) if not confirmed: return for item in list(self.datagrid.SelectedItems): SharedParameter.delete_from_definition_file( self.datagrid.SelectedItems, definition_file) self.data_grid_content.Remove(item)
def Delete(): global files global lengths directory = forms.pick_folder( "Select parent folder of backup families or files to be purged") if directory: DeleteRecursive(directory) b = convert_unit(lengths, SIZE_UNIT.MB) message = 'You are about to delete ' +\ str(files) + ' files with a total of ' + str(b) + ' MB. Are you sure?' if forms.alert(message, ok=False, yes=True, no=True, exitscript=True): for file in files_to_delete: file.Delete() print(str(files) + ' files with a total of ' + str(b) + ' MB deleted.')
def colorize_grouptypes_in_views(views): view_names = [x.Name for x in views] text = \ "Do you want to override colors on these views:\n" \ + "\n".join(view_names) if not forms.alert(text, yes=True, cancel=True, no=False): return groups_dict = collect_groups(views) logger.debug(groups_dict) # prepare colors across selected views groups_colors = prepare_colors(groups_dict) logger.debug(groups_colors) with revit.Transaction(__title__ + ""): for view in views: # apply overrides to each view colorize_grouptypes_in_view(view, groups_colors)
def who_created_selection(): selection = revit.get_selection() if revit.doc.IsWorkshared: if selection and len(selection) == 1: eh = revit.query.get_history(selection.first) forms.alert('Creator: {0}\n' 'Current Owner: {1}\n' 'Last Changed By: {2}'.format(eh.creator, eh.owner, eh.last_changed_by)) else: forms.alert('Exactly one element must be selected.') else: forms.alert('Model is not workshared.')
def verify_name(self): if not self.pat_name: forms.alert('Type a name for the pattern first') return False elif not re.search('[a-zA-Z0-9]', self.pat_name): forms.alert('Pattern name must have at least ' 'one character or digit') return False elif self.pat_name.lower() in readonly_patterns: forms.alert( 'Read-Only pattern with name "{}" already exists '.format( self.pat_name)) return False return True
def pick_files(files_filter): logger.debug(files_filter) result = [] for i in range(10): paths = forms.pick_file(files_filter=files_filter + "|All files (*.*)|*.*", restore_dir=True, multi_file=True) if not paths: break result += list(paths) logger.info("Files selected: " + "\n".join(paths)) form_result = forms.alert("Add more files?", yes=True, cancel=True) if not form_result: break return set(result)
def colorize_grouptypes_in_views(views): """Colorize groups by type in given views""" view_names = [x.Name for x in views] text = ("Do you want to colorize groups by type on these views:\n\n" + "\n".join(view_names)) if not forms.alert(text, yes=True, cancel=True, no=False): return groups_dict = collect_groups(views) groups_dict = filter_group_types(groups_dict) logger.debug(groups_dict) # prepare colors across selected views groups_colors = prepare_colors(groups_dict) logger.debug(groups_colors) with revit.Transaction(__title__): for view in views: # apply overrides to each view colorize_grouptypes_in_view(view, groups_colors)
def who_created_selection(): selection = revit.get_selection() if revit.doc.IsWorkshared: if selection and len(selection) == 1: wti = DB.WorksharingUtils.GetWorksharingTooltipInfo( revit.doc, selection.first.Id ) forms.alert('Creator: {0}\n' 'Current Owner: {1}\n' 'Last Changed By: {2}'.format(wti.Creator, wti.Owner, wti.LastChangedBy)) else: forms.alert('Exactly one element must be selected.') else: forms.alert('Model is not workshared.')
def import_keynotes(self, sender, args): # verify existing keynotes when importing # maybe allow for merge conflict? kfile = forms.pick_file('txt') if kfile: if not coreutils.check_revittxt_encoding(kfile): logger.debug('Incorrect file encoding: %s' % kfile) forms.alert("File must be encoded in UTF-16 (UCS-2 LE)") else: logger.debug('Importing keynotes from: %s' % kfile) res = forms.alert("Do you want me to skip duplicates if any?", yes=True, no=True) try: kdb.import_legacy_keynotes(self._conn, kfile, skip_dup=res) except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: logger.debug('Importing legacy keynotes failed | %s' % ex) forms.alert(str(ex)) finally: self._update_ktree(active_catkey=self._allcat)
def edit_category(self, sender, args): selected_category = self.selected_category selected_keynote = self.selected_keynote # determine where the category is coming from # selected category in drop-down if selected_category: target_keynote = selected_category # or selected category in keynotes list elif selected_keynote and not selected_keynote.parent_key: target_keynote = selected_keynote if target_keynote: if target_keynote.locked: forms.alert( 'Category is locked and is being edited by {}. ' 'Wait until their changes are committed. ' 'Meanwhile you can use or modify the keynotes ' 'under this category.'.format( '\"%s\"' % target_keynote.owner if target_keynote. owner else 'and unknown user')) else: try: EditRecordWindow(self, self._conn, kdb.EDIT_MODE_EDIT_CATEG, rkeynote=target_keynote).show() # make sure to relaod on close self._needs_update = True except System.TimeoutException as toutex: forms.alert( toutex.Message, expanded="{}::edit_category() [timeout]".format( self.__class__.__name__)) except Exception as ex: forms.alert(str(ex), expanded="{}::edit_category()".format( self.__class__.__name__)) finally: self._update_ktree() if selected_keynote: self._update_ktree_knotes()
def pick_chain(doc): selection = revit.selection.get_selection() # last_selection = selection.element_ids selected_curve = revit.pick_element("Select curves to sort by") if not selected_curve: forms.alert("Nothing selected") return None, None logger.debug("selected_curve: %s" % str(selected_curve.Id)) try: selected_curve.GeometryCurve except: forms.alert( "Error! Selected element is not a Curve.\nOr it have no GeometryCurve parameter" ) return None, None if not selected_curve.GeometryCurve.IsBound: forms.alert("Error! Curve cannot be bounded") # chain selection_list_sorted, selection_list_sorted_isreversed = _find_curve_chain( selected_curve, doc) logger.debug("selection_list_sorted: %s" % selection_list_sorted) if len(selection_list_sorted) > 1: # TODO undo selection.set_to(selection_list_sorted) form_result = TaskDialog.Show( "Select curve chain?", "Curve chain found. Use it?\nIf not, only one selected curve will be used", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) # selection.set_to(last_selection) if str(form_result) == "Yes": return selection_list_sorted, selection_list_sorted_isreversed logger.debug("Selected_curve: %s" % [selected_curve.Id]) return [selected_curve.Id], None
def pick_key(self, sender, args): # remove previously reserved if self._reserved_key: try: kdb.release_key(self._conn, self._reserved_key, category=self._cat) except System.TimeoutException as toutex: forms.alert(toutex.Message) return try: categories = kdb.get_categories(self._conn) keynotes = kdb.get_keynotes(self._conn) locks = kdb.get_locks(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return # collect existing keys reserved_keys = [x.key for x in categories] reserved_keys.extend([x.key for x in keynotes]) reserved_keys.extend([x.LockTargetRecordKey for x in locks]) # ask for a unique new key new_key = forms.ask_for_unique_string( prompt='Enter a Unique Key', title=self.Title, reserved_values=reserved_keys, owner=self) if new_key: try: kdb.reserve_key(self._conn, new_key, category=self._cat) except System.TimeoutException as toutex: forms.alert(toutex.Message) return self._reserved_key = new_key # set the key value on the button self.active_key = new_key
def edit_category(self, sender, args): selected_category = self.selected_category if selected_category: if selected_category.locked: forms.alert('Category is locked and is being edited by {}. ' 'Wait until their changes are committed. ' 'Meanwhile you can use or modify the keynotes ' 'under this category.'.format( '\"%s\"' % selected_category.owner if selected_category. owner else 'and unknown user')) else: try: EditRecordWindow(self, self._conn, kdb.EDIT_MODE_EDIT_CATEG, rkeynote=selected_category).show() except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: forms.alert(str(ex)) finally: self._update_ktree()
def rekey_keynote(self, sender, args): forms.alert("Not yet implemented. Coming soon.")
def enable_history(self, sender, args): forms.alert("Not yet implemented. Coming soon.")
Usage: testdocopt (-h | --help) testdocopt (-V | --version) testdocopt -e <encod> <src_file> Options: -h, --help Show this help -V, --version Show command version -e <encod>, --encode <encod> File encoding [default: utf-8] """ # noqa import sys from pyrevit import forms from pyrevit import script import docopt logger = script.get_logger() try: logger.debug(sys.argv) args = docopt.docopt(__doc__, version='testdocopt {}'.format('v0.1'), help=True) print(args) except docopt.DocoptExit: forms.alert('This command needs command line arguments. ' 'Run from pyRevit search and provide arguments')
def rekey_category(self, sender, args): forms.alert("Not yet implemented. Coming soon.")
def all_keynotes(self): try: return kdb.get_keynotes(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return []
output = script.get_output() paths = DB.FilteredElementCollector(revit.doc) \ .OfCategory(DB.BuiltInCategory.OST_StairsPaths) \ .WhereElementIsNotElementType() path_types = DB.FilteredElementCollector(revit.doc) \ .OfCategory(DB.BuiltInCategory.OST_StairsPaths) \ .WhereElementIsElementType() auto_paths = [p for p in paths if revit.doc.GetElement(p.GetTypeId()).StairsPathDirection == DB.Architecture.StairsPathDirection.AutomaticUpDown] up_path_id = [p.Id for p in path_types if p.StairsPathDirection == DB.Architecture.StairsPathDirection.AlwaysUp] stairs = DB.FilteredElementCollector(revit.doc) \ .OfCategory(DB.BuiltInCategory.OST_Stairs) \ .WhereElementIsNotElementType() counter = 0 with revit.Transaction("Set all Stair Paths to Up"): for a in auto_paths: a.ChangeTypeId(up_path_id[0]) counter += 1 for stair in stairs: if stair.get_Parameter(DB.BuiltInParameter.STAIRS_INST_ALWAYS_UP): stair.get_Parameter(DB.BuiltInParameter.STAIRS_INST_ALWAYS_UP).Set(1) forms.alert("Changed Stair Path direction to UP for {} stairs".format(counter))
title="Select Parameters", multiselect=True, ) or [] if __name__ == '__main__': forms.check_familydoc(exitscript=True) family_cfg_file = get_config_file() if family_cfg_file: family_params = get_parameters() if family_params: inctypes = incdefault = False # ask user to include family type definitions inctypes = forms.alert( "Do you want to export family types as well?", yes=True, no=True ) # if said no, ask if the current param values should be included if not inctypes: incdefault = forms.alert( "Do you want to include the current parameter values as " "default? Otherwise the parameters will not include any " "value and their default value will be assigned " "by Revit at import.", yes=True, no=True ) family_configs = \ read_configs(family_params, include_types=inctypes, include_defaults=incdefault)
def show_keynote_history(self, sender, args): forms.alert("Not yet implemented. Coming soon.")
def commit(self): if self._mode == kdb.EDIT_MODE_ADD_CATEG: if not self.active_key: forms.alert('Category must have a unique key.') return False elif not self.active_text.strip(): forms.alert('Category must have a title.') return False logger.debug('Adding category: {} {}'.format( self.active_key, self.active_text)) try: self._res = kdb.add_category(self._conn, self.active_key, self.active_text) kdb.end_edit(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return False elif self._mode == kdb.EDIT_MODE_EDIT_CATEG: if not self.active_text: forms.alert('Existing title is removed. ' 'Category must have a title.') return False try: # update category key if changed if self.active_key != self._rkeynote.key: self._res = kdb.rekey_category(self._conn, self._rkeynote.key, self.active_key) # update category title if changed if self.active_text != self._rkeynote.text: kdb.update_category_title(self._conn, self.active_key, self.active_text) kdb.end_edit(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return False elif self._mode == kdb.EDIT_MODE_ADD_KEYNOTE: if not self.active_key: forms.alert('Keynote must have a unique key.') return False elif not self.active_text: forms.alert('Keynote must have text.') return False elif not self.active_parent_key: forms.alert('Keynote must have a parent.') return False try: self._res = kdb.add_keynote(self._conn, self.active_key, self.active_text, self.active_parent_key) kdb.end_edit(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return False elif self._mode == kdb.EDIT_MODE_EDIT_KEYNOTE: if not self.active_text: forms.alert( 'Existing text is removed. Keynote must have text.') return False try: # update keynote key if changed if self.active_key != self._rkeynote.key: self._res = kdb.rekey_keynote(self._conn, self._rkeynote.key, self.active_key) # update keynote title if changed if self.active_text != self._rkeynote.text: kdb.update_keynote_text(self._conn, self.active_key, self.active_text) # update keynote parent if self.active_parent_key != self._rkeynote.parent_key: kdb.move_keynote(self._conn, self.active_key, self.active_parent_key) kdb.end_edit(self._conn) except System.TimeoutException as toutex: forms.alert(toutex.Message) return False return True
from pyrevit import forms __doc__ = 'This tool will create a workset for the selected linked '\ 'element base on its name. If the model is not workshared, '\ 'it will be converted to workshared model.' logger = script.get_logger() selection = revit.get_selection() linkedModelName = '' if len(selection) > 0: for el in selection: if isinstance(el, DB.RevitLinkInstance): linkedModelName = el.Name.split(':')[0] elif isinstance(el, DB.ImportInstance): linkedModelName = el.LookupParameter('Name').AsString() if linkedModelName: if not revit.doc.IsWorkshared and revit.doc.CanEnableWorksharing: revit.doc.EnableWorksharing('Shared Levels and Grids', 'Workset1') with revit.Transaction('Create Workset for linked model'): newWs = DB.Workset.Create(revit.doc, linkedModelName) worksetParam = \ el.Parameter[DB.BuiltInParameter.ELEM_PARTITION_PARAM] worksetParam.Set(newWs.Id.IntegerValue) else: forms.alert('At least one linked element must be selected.')
def pick_parent(self, sender, args): # TODO: pick_parent # categories = get_categories(self._conn) # keynotes_tree = get_keynotes_tree(self._conn) forms.alert('Pick parent...')
from rpm.system.ui import UI from rpm.system.update import Update from rpm.system.session import Session from pyrevit import script from pyrevit import forms update = 'Discard all changes and update now' cancel = 'Cancel' res = forms.alert('Updating will discard all local changes in your extension repositories!', title = 'Force Extension Update', options = [update, cancel]) if res == update: out = script.get_output() UI.printLogo() UI.printTitle() Update.extensions(True) out.print_html('<br><br>Update has finished. Reloading ...<br><br>') Session.reload()
def translate(self, sender, args): forms.alert("Not yet implemented. Coming soon.")
__title__ = "Wall\n Equal Length" #Title of the extension __author__ = "Shahabaz Sha" from pyrevit.framework import List from pyrevit import revit, DB from pyrevit import forms #getting selection from user # __context__ = 'Selection' doc = __revit__.ActiveUIDocument.Document uidoc = __revit__.ActiveUIDocument curview = doc.ActiveView # gets current view if isinstance(curview, DB.ViewSheet): forms.alert("You're on a Sheet. Activate a model view please.", exitscript=True) length_feet = float(forms.ask_for_string( "Enter length in meters")) / 0.3048 # sometimes revit interprets 1 > 1.0 target_parameter = DB.BuiltInParameter.CURVE_ELEM_LENGTH # FAMILY_TOP_LEVEL_PARAM, FAMILY_BASE_LEVEL_PARAM param_id = DB.ElementId(target_parameter) param_prov = DB.ParameterValueProvider(param_id) param_equality = DB.FilterNumericEquals() # equality class value_rule = DB.FilterDoubleRule(param_prov, param_equality, length_feet, 1e-3 / 0.3048) # tolerance of 1 mm param_filter = DB.ElementParameterFilter(value_rule) same_cat_elements = \ DB.FilteredElementCollector(doc,curview.Id)\ .OfCategory(DB.BuiltInCategory.OST_Walls)\
def __init__(self, xaml_file_name): forms.WPFWindow.__init__(self, xaml_file_name) # verify keynote file existence self._kfile = revit.query.get_keynote_file(doc=revit.doc) if not self._kfile or not op.exists(self._kfile): self._kfile = None forms.alert("Keynote file is not accessible. " "Please select a keynote file.") self._change_kfile() # if a keynote file is still not set, return if not self._kfile: raise Exception('Keynote file is not setup.') self._conn = None try: self._conn = kdb.connect(self._kfile) except System.TimeoutException as toutex: forms.alert(toutex.Message, exitscript=True) except Exception as ex: logger.debug('Connection failed | %s' % ex) res = forms.alert( "Existing keynote file needs to be converted to " "a format usable by this tool. The resulting keynote " "file is still readble by Revit and could be shared " "with other projects. Users should NOT be making changes to " "the existing keynote file during the conversion process.\n" "Are you sure you want to convert?", options=["Convert", "Give me more info"]) if res: if res == "Convert": try: self._convert_existing() forms.alert("Conversion completed!") if not self._conn: forms.alert( "Launch the tool again to manage keynotes.", exitscript=True) except Exception as convex: logger.debug('Legacy conversion failed | %s' % convex) forms.alert("Conversion failed! %s" % convex, exitscript=True) elif res == "Give me more info": script.open_url('https://eirannejad.github.io/pyRevit') script.exit() else: forms.alert("Keynote file is not yet converted.", exitscript=True) self._cache = [] self._allcat = kdb.RKeynote(key='', text='-- ALL CATEGORIES --', parent_key='', locked=False, owner='', children=None) self._config = script.get_config() self._used_keysdict = self.get_used_keynote_elements() self.load_config() self.search_tb.Focus()