diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml index 460c9fd38..4e2af0117 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml @@ -3,6 +3,7 @@ Title="MainWindow" Foreground="#000" Height="325" Width="690" Margin="0" + SizeToContent="Width" ShowInTaskbar="False" BorderThickness="0" Background="{x:Null}" diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/ExtensionsWindow.xaml b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/ExtensionsWindow.xaml index e0f659e26..c09491ea5 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/ExtensionsWindow.xaml +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/ExtensionsWindow.xaml @@ -10,6 +10,10 @@ + + diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/script.py index 578588d8c..f507df7ba 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/script.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Extensions.smartbutton/script.py @@ -337,11 +337,6 @@ def update_ext_info(self, sender, args): else: self.hide_element(self.ext_infopanel) - def handle_url_click(self, sender, args): - """Callback for handling click on package website url - """ - script.open_url(sender.NavigateUri.AbsoluteUri) - def handle_private_repo(self, sender, args): """Callback for updating private status of a package """ diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Search.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Search.pushbutton/script.py index 308483f3f..ed38df390 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Search.pushbutton/script.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Search.pushbutton/script.py @@ -160,7 +160,7 @@ def open_in_editor(editor_name, selected_cmd, altsrc=False): NP_SWITCH, CONFIG_SWITCH, ALT_FLAG], - search_tip='pyRevit Search') + search_tip='type to search') logger.debug('matched command: {}'.format(matched_cmdname)) logger.debug('arguments: {}'.format(matched_cmdargs)) diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Spy.pulldown/List Elements.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Spy.pulldown/List Elements.pushbutton/script.py index 5a77d157d..a278bda1a 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Spy.pulldown/List Elements.pushbutton/script.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/tools.stack3/Spy.pulldown/List Elements.pushbutton/script.py @@ -82,12 +82,11 @@ print(i.Name) elif selected_switch == 'Line Styles': - c = revit.doc.Settings.Categories.get_Item(DB.BuiltInCategory.OST_Lines) - subcats = c.SubCategories - - for lineStyle in subcats: - print("STYLE NAME: {0} ID: {1}".format(lineStyle.Name.ljust(40), - lineStyle.Id.ToString())) + for lineStyle in revit.query.get_line_styles(doc=revit.doc): + print("STYLE NAME: {} ID: {} ({})".format( + lineStyle.Name.ljust(40), + lineStyle.Id.ToString(), + lineStyle)) elif selected_switch == 'Model / Detail / Sketch Lines': cat_list = List[DB.BuiltInCategory]([DB.BuiltInCategory.OST_Lines, diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/KeynoteManagerWindow.xaml b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/KeynoteManagerWindow.xaml index 0bdcaad1a..2a2c50b59 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/KeynoteManagerWindow.xaml +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/KeynoteManagerWindow.xaml @@ -150,8 +150,8 @@ @@ -82,7 +86,9 @@ + Kudos to Ryan McCullough for PrintFromIndex + diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Print.pulldown/Print Ordered Sheet Index.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Print.pulldown/Print Ordered Sheet Index.pushbutton/script.py index d6eaee16d..092c25b6c 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Print.pulldown/Print Ordered Sheet Index.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Print.pulldown/Print Ordered Sheet Index.pushbutton/script.py @@ -1,13 +1,20 @@ """Print sheets in order from a sheet index. -Shift-Click: +Note: When using the `Combine into one file` option, -the tool adds invisible characters at the start of -the sheet names to push Revit's interenal printing -engine to sort the sheets correctly per the drawing -index order. Shift-Clicking the tool will remove all -these characters from the sheet numbers, in case an error -in the tool causes these characters to remain. +the tool adds non-printable character u'\u200e' +(Left-To-Right Mark) at the start of the sheet names +to push Revit's interenal printing engine to sort +the sheets correctly per the drawing index order. + +Make sure your drawings indices consider this +when filtering for sheet numbers. + +Shift-Click: +Shift-Clicking the tool will remove all +non-printable characters from the sheet numbers, +in case an error in the tool causes these characters +to remain. """ import os.path as op @@ -368,9 +375,6 @@ def print_sheets(self, sender, args): else: self._print_sheets_in_order() - def handle_url_click(self, sender, args): - script.open_url('https://github.com/McCulloughRT/PrintFromIndex') - def preview_mouse_down(self, sender, args): if isinstance(sender, Windows.Controls.ListViewItem): if sender.DataContext.printable: diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/ReOrderWindow.xaml b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/ReOrderWindow.xaml index 4b1a574c0..71a7ab9a6 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/ReOrderWindow.xaml +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/ReOrderWindow.xaml @@ -15,7 +15,7 @@ - + - + + + + Usage: Enter a regular expression pattern in this box. This pattern is used to detect changes in + Sheet Numbers and group indices. For example, to group using the discipline identifier in + Sheet Number (A in A1.00), use "([A-Z])\d". The () in pattern select the discipline identifier as a group + which is used to group sheet ranges. + + See Regexr on how to use Regular Expressions + + + + - List of the sheets (Drag to manually reorder): + List of the sheets (Drag to manually reorder) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py index 9c8d88785..bc494b273 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py @@ -1,5 +1,7 @@ """Print items in order from a sheet index.""" #pylint: disable=W0613,E0401,C0103 +import re + from pyrevit import forms from pyrevit import revit, DB from pyrevit import script @@ -25,8 +27,14 @@ class ReOrderWindow(forms.WPFWindow): def __init__(self, xaml_file_name): forms.WPFWindow.__init__(self, xaml_file_name) + self._config = script.get_config() + self._setup_item_params_combobox() + self.grouping_pattern = \ + self._config.get_option('index_grouping_pattern', + r'([A-Z])\d') + @property def items_list(self): return self.items_dg.ItemsSource @@ -41,9 +49,43 @@ def items_list(self, value): def selected_item_param(self): return self.orderparams_cb.SelectedItem + @property + def grouping_pattern(self): + pattern = self.indexgroup_tb.Text + try: + re.compile(pattern) + return pattern + except Exception: + return "" + + @grouping_pattern.setter + def grouping_pattern(self, value): + self.indexgroup_tb.Text = value + + def _refresh(self): + existing_items = self.items_list + self.items_list = [] + self.items_list = existing_items + def _update_order_indices(self): - for idx, item in enumerate(self.items_list): - item.order_index = idx + if self.grouping_pattern: + last_groupid = '' + grouping_index = 0 + grouping_range = 1000 + for idx, item in enumerate(self.items_list): + match = re.search(self.grouping_pattern, item.number) + if match and match.groups(): + groupid = match.groups()[0] + if groupid != last_groupid: + last_groupid = groupid + grouping_index += 1 + + item.order_index = (grouping_range * grouping_index) + idx + else: + item.order_index = idx + else: + for idx, item in enumerate(self.items_list): + item.order_index = idx def _setup_item_params_combobox(self): items = revit.query.get_sheets() @@ -99,6 +141,9 @@ def sorting_changed(self, sender, args): elif order_param == 'name': self.items_list = sorted(self.items_list, key=lambda x: x.name) + def grouping_pattern_changed(self, sender, args): + self._refresh() + def move_to_top(self, sender, args): selected, non_selected = self._get_selected_nonselected() new_list = self._insert_list_in_list(selected, non_selected, 0) @@ -137,6 +182,8 @@ def move_to_bottom(self, sender, args): def reorder_items(self, sender, args): self.Close() + self._config.set_option('index_grouping_pattern', + self.grouping_pattern) with revit.Transaction('Reorder Sheets'): for item in self.items_list: idx_param = \ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/Select Sheets.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/Select Sheets.pushbutton/script.py new file mode 100644 index 000000000..9a3d82121 --- /dev/null +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/Select Sheets.pushbutton/script.py @@ -0,0 +1,10 @@ +"""Change the selected sheet names.""" +#pylint: disable=import-error,invalid-name +from pyrevit import revit +from pyrevit import forms + +selection = revit.get_selection() +sel_sheets = forms.select_sheets(title='Select Sheets') + +if sel_sheets: + selection.set_to(sel_sheets) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/_layout b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/_layout index d2dc06df4..904833afa 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/_layout +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/_layout @@ -6,6 +6,7 @@ Reorder Selected Viewport Copy Sheets to Open Documents Batch Sheet Maker ----- +Select Sheets Rename Selected Sheets Select TitleBlocks on Sheets Set Crop Region To Selected Shape diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Paint.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Paint.pushbutton/script.py index 830bca529..c43b173d2 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Paint.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Paint.pushbutton/script.py @@ -2,7 +2,9 @@ #pylint: disable=E0401,C0111,W0613,C0103,broad-except from pyrevit import revit, UI from pyrevit import forms +from pyrevit import script +logger = script.get_logger() with forms.WarningBar(title='Pick source object:'): source_face = revit.pick_face() @@ -12,6 +14,8 @@ material_id = source_face.MaterialElementId material = revit.doc.GetElement(material_id) + logger.debug('Selected material id:%s name:%s', material.Id, material.Name) + with forms.WarningBar(title='Pick faces to match materials:'): while True: try: diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Team.pulldown/Who Did That.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Team.pulldown/Who Did That.pushbutton/script.py index 5d2b960eb..4fcfcd3c1 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Team.pulldown/Who Did That.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Team.pulldown/Who Did That.pushbutton/script.py @@ -50,16 +50,13 @@ 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 - ) + eh = revit.query.get_history(selection.first) forms.alert('Creator: {0}\n' 'Current Owner: {1}\n' - 'Last Changed By: {2}'.format(wti.Creator, - wti.Owner, - wti.LastChangedBy)) + 'Last Changed By: {2}'.format(eh.creator, + eh.owner, + eh.last_changed_by)) else: forms.alert('Exactly one element must be selected.') else: diff --git a/pyrevitlib/pyrevit/coreutils/__init__.py b/pyrevitlib/pyrevit/coreutils/__init__.py index 3805c8852..de1fd2cca 100644 --- a/pyrevitlib/pyrevit/coreutils/__init__.py +++ b/pyrevitlib/pyrevit/coreutils/__init__.py @@ -1438,3 +1438,15 @@ def get_reg_key(key, subkey): return wr.OpenKey(key, subkey, 0, wr.KEY_READ) except Exception: return None + + +def kill_tasks(task_name): + """Kill running tasks matching task_name + + Args: + task_name (str): task name + + Example: + >>> kill_tasks('Revit.exe') + """ + os.system("taskkill /f /im %s" % task_name) \ No newline at end of file diff --git a/pyrevitlib/pyrevit/forms/__init__.py b/pyrevitlib/pyrevit/forms/__init__.py index c7a2f78af..0103dd9f3 100644 --- a/pyrevitlib/pyrevit/forms/__init__.py +++ b/pyrevitlib/pyrevit/forms/__init__.py @@ -12,6 +12,7 @@ import threading from functools import wraps import datetime +import webbrowser from pyrevit import HOST_APP, EXEC_PARAMS, BIN_DIR from pyrevit.compat import safe_strtype @@ -210,6 +211,10 @@ def enable_element(*wpf_elements): for wpfel in wpf_elements: wpfel.IsEnabled = True + def handle_url_click(self, sender, args): + """Callback for handling click on package website url""" + return webbrowser.open_new_tab(sender.NavigateUri.AbsoluteUri) + class TemplateUserInputWindow(WPFWindow): """Base class for pyRevit user input standard forms. diff --git a/pyrevitlib/pyrevit/revit/db/query.py b/pyrevitlib/pyrevit/revit/db/query.py index 8bbffd62b..a98143f84 100644 --- a/pyrevitlib/pyrevit/revit/db/query.py +++ b/pyrevitlib/pyrevit/revit/db/query.py @@ -45,6 +45,9 @@ ['sheet_num', 'sheet_name', 'detail_num', 'ref_viewid']) +ElementHistory = namedtuple('ElementHistory', + ['creator', 'owner', 'last_changed_by']) + def get_name(element, title_on_sheet=False): # grab viewname correctly @@ -1083,3 +1086,24 @@ def yield_unreferenced_views(doc=None, all_views=None): # if it has NO referring views, yield if len(list(yield_referring_views(view))) == 0: yield view.Id + + +def get_line_categories(doc=None): + doc = doc or HOST_APP.doc + lines_cat = doc.Settings.Categories.get_Item(DB.BuiltInCategory.OST_Lines) + return lines_cat.SubCategories + + +def get_line_styles(doc=None): + return [x.GetGraphicsStyle(DB.GraphicsStyleType.Projection) + for x in get_line_categories(doc=doc)] + + +def get_history(target_element): + doc = target_element.Document + if doc.IsWorkshared: + wti = DB.WorksharingUtils.GetWorksharingTooltipInfo(doc, + target_element.Id) + return ElementHistory(creator=wti.Creator, + owner=wti.Owner, + last_changed_by=wti.LastChangedBy) diff --git a/pyrevitlib/pyrevit/version b/pyrevitlib/pyrevit/version index c3cb48d5c..f75b13303 100644 --- a/pyrevitlib/pyrevit/version +++ b/pyrevitlib/pyrevit/version @@ -1 +1 @@ -4.6.15 \ No newline at end of file +4.6.16 \ No newline at end of file diff --git a/release/pyRevit.aip b/release/pyRevit.aip index 0eead32a4..14b25d64d 100644 --- a/release/pyRevit.aip +++ b/release/pyRevit.aip @@ -1,5 +1,5 @@ - + @@ -27,10 +27,10 @@ - + - + @@ -248,6 +248,7 @@ + @@ -433,7 +434,7 @@ - + @@ -881,6 +882,7 @@ + @@ -897,7 +899,7 @@ - + @@ -5433,6 +5435,7 @@ + @@ -5531,7 +5534,7 @@ - +