public SortableBindingList <SearchHit> Run( JtLogFile log, out string message) { message = string.Empty; SortableBindingList <SearchHit> data = new SortableBindingList <SearchHit>(); Parameter p; // Do we search for some specific parameters? List <Definition> defs = null; string parameterName = _searchOptions.ParameterName; if (null != parameterName) { foreach (Element e in _collector) { if (_searchOptions.BuiltInParams) { BuiltInParameter bip = ( BuiltInParameter )Enum.Parse( typeof(BuiltInParameter), parameterName, true); p = e.get_Parameter(bip); if (null != p) { defs = new List <Definition>(1); defs.Add(p.Definition); } } else { //p = e.get_Parameter( parameterName ); IList <Parameter> ps = e.GetParameters( parameterName); if (0 < ps.Count) { defs = new List <Definition>(ps.Count); foreach (Parameter q in ps) { defs.Add(q.Definition); } } } //if( null != p ) //{ // def = p.Definition; // break; //} } if (null == defs) { message = string.Format( "None of the selected elements have any parameter '{0}'", parameterName); return(data); } } // Set up regular expression for search string string searchText = _searchOptions.SearchString; RegexOptions opt = RegexOptions.Compiled; if (!_searchOptions.Regex) { searchText = Regex.Escape(searchText); } if (!_searchOptions.MatchCase) { opt |= RegexOptions.IgnoreCase; } if (_searchOptions.WholeWord) { searchText = "^" + searchText + "$"; } Regex regex = new Regex(searchText, opt); // Start searching foreach (Element e in _collector) { log.Log("Document: " + e.Document.Title); break; } log.Log("Search string: " + _searchOptions.SearchString); log.Log("Parameter: " + _searchOptions.ParameterName); log.Log("Match case: " + _searchOptions.MatchCase); log.Log("Whole word: " + _searchOptions.WholeWord); log.Log("Regular expression: " + _searchOptions.Regex); log.Log("Built-in parameters: " + _searchOptions.BuiltInParams); bool foundOnElement; foreach (Element e in _collector) { foundOnElement = false; if (null != defs) { foreach (Definition d in defs) { p = e.get_Parameter(d); foundOnElement |= SearchParameter( data, e, p, parameterName, regex); } } else if (_searchOptions.BuiltInParams) { foreach (BuiltInParameter a in _bips) { // Handle a potential exception for access // to certain parameters. This should not // be needed, because get_Parameter should // simply return null if the parameter is // not available or inaccessible. Currently // only required due to SPR #211511 [exceptions // accessing built-in parameters on views]: try { p = e.get_Parameter(a); foundOnElement |= SearchParameter( data, e, p, a.ToString(), regex); } catch (Exception ex) { SearchHit h = new SearchHit( e, a.ToString(), "", "", 0); Debug.Print(string.Format( "{0} searching {1}", ex.Message, h.ToString())); } } } else { ParameterSet pset = e.Parameters; foreach (Parameter q in pset) { foundOnElement |= SearchParameter( data, e, q, null, regex); } } ++_counters.ElementsSearched; if (foundOnElement) { ++_counters.ElementsHit; } } log.Log(string.Format( "{0} element{1} and {2} parameter{3} searched.", _counters.ElementsSearched, PluralSuffix(_counters.ElementsSearched), _counters.ParametersSearched, PluralSuffix(_counters.ParametersSearched))); log.Log(string.Format( "{0} total hit{1} found on {2} element{3} and {4} parameter{5}{6}", _counters.Hits, PluralSuffix(_counters.Hits), _counters.ElementsHit, PluralSuffix(_counters.ElementsHit), _counters.ParametersHit, PluralSuffix(_counters.ParametersHit), 0 == _counters.Hits ? "." : ":")); foreach (SearchHit h in data) { log.Log(h.ToString()); } return(data); }
/// <summary> /// The Revit 2012 API provides the new method /// Autodesk.Revit.UI.Selection.GetElementIds /// returning an ICollection of ElementId. In /// Revit 2011, we implement it ourselves for /// backwards compatibility. /// </summary> //ICollection<ElementId> GetSelectedElementIds( // UIDocument uidoc ) //{ // SelElementSet ss = uidoc.Selection.Elements; // List<ElementId> ids = new List<ElementId>( // ss.Size ); // foreach( Element e in ss ) // { // ids.Add( e.Id ); // } // return ids; //} /// <summary> /// External command mainline. /// Determine Revit application window handle. /// Prompt user for search string and options. /// Retrieve all requested elements and search their parameters. /// List the result in a log file and a data container. /// </summary> public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; ICollection <ElementId> selids = uidoc.Selection.GetElementIds(); try { using (JtLogFile log = new JtLogFile("SearchString")) { SortableBindingList <SearchHit> data = null; while (null == data || 0 == data.Count) { // Display search form: SearchForm form = new SearchForm(log.Path); DialogResult r = form.ShowDialog(); if (DialogResult.Cancel == r) { message = string.Empty; return(Result.Cancelled); } if (form.CurrentSelection && 0 == selids.Count) { InfoMsg("Sorry; you cannot search the current element selection, because it is empty."); continue; } // Run filtered element collector: #region Set up filtered element collector FilteredElementCollector a = form.CurrentView ? new FilteredElementCollector( doc, doc.ActiveView.Id) : form.CurrentSelection ? new FilteredElementCollector(doc, uidoc.Selection.GetElementIds()) : new FilteredElementCollector(doc); if (form.ElementType && form.NonElementType) { a.WhereElementIsElementType(); FilteredElementCollector b = form.CurrentView ? new FilteredElementCollector(doc, doc.ActiveView.Id) : new FilteredElementCollector(doc); b.WhereElementIsNotElementType(); a.UnionWith(b); } else if (form.ElementType) { a.WhereElementIsElementType(); } else if (form.NonElementType) { a.WhereElementIsNotElementType(); } else { message = "Please select at least one or both of Element type and non-Element type."; return(Result.Failed); } if (!form.AllCategories) { BuiltInCategory bic = ( BuiltInCategory )Enum.Parse( typeof(BuiltInCategory), form.CategoryName); a.OfCategory(bic); } #endregion // Set up filtered element collector // Search element parameter data: StringSearcher ss = new StringSearcher( a, form.SearchOptions); try { data = ss.Run(log, out message); if (0 == data.Count) { InfoMsg(0 < message.Length ? message : "No occurrences found."); } } catch (ArgumentException ex) { if (ex.StackTrace.Contains( "RegularExpressions.RegexParser.ScanRegex")) { InfoMsg("Invalid regular expression. Error message:\r\n" + ex.Message + "\r\nIf you don't know what a regular expression is, don't use it" + "\r\n(cheat sheet: http://regexlib.com/cheatsheet.aspx)."); } else { throw ex; } } } App.ShowForm(data); return(Result.Succeeded); } } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }