Supporting Search and Replace
A module can tie into the search and replace system by registering a SearchProvider
implementation with the DesignerContext
. The SearchProvider
will be used to get information about search options, and will be used to generate potential search matches.
How the Search and Replace Process Works
The basic process is simple:
- The
SearchProvider
generates potential search results (SearchObject). - The search and replace system will try to match the text of the
SearchObject
to the search pattern. - If the object passes, it will be displayed to the user.
- The user can then double-click on the object, wch delegates to the
SearchObject.locate()
function, or can try to replace the value.
The SearchObjects
generated by the SearchProvider
are returned through an Iterator, with the idea being that they are generated on the fly, so that only matching results need to be kept in memory. The SearchObject
implementation will be unique to the provider, as it must know how to locate and replace the resource that it represents.
Refining the Search: Categories and Selected Objects
The SearchProvider
can use two mechanisms to refine the objects to be searched.
The first, called categories, are a simple way to provide a broad choice. They are displayed as check boxes under the search provider entry on the search window, and the selected objects are passed back to the provider when the search is executed.
The second method is through the use of selectable objects. With this mechanism, the search provider will be displayed with a link that will call into the search provider with a SelectedObjectsHandler
. The search provider can display a dialog to select which "items" should be searched. The definition of an item is free-form, and can be as simple or complex as the provider wants. Like categories, the selected objects will be passed into the main search function when the search is executed.
Common Design Paradigms and Tools
While the implementation of the search and replace interface is specific to each module, there are certain concerns and patterns that come up frequently.
SearchObject Information
SearchObjects
have the ability to provide an Icon, an Owner, and a Name. Some experimentation may be necessary to find the right amount of information to provide in order to make the search results intuitive and easy to identify.
For example, returning values of "Button" and "Text" for owner and name respectively, on the Text property of a Button might seem clear at first, but once multiple buttons appear on a screen, it becomes impossible to distinguish them. Including the actual component name in the "owner" string solves this proboem, but can then make it difficult to decipher at a glance what the result is. Using a button image for the icon can provide the final visual clue that the user needs to order to understand quickly.
Iterator Management
While the Iterator mechanism works great for reducing the amount of memory required for searching, it can sometimes be unwieldy to deal with in anything but the simplest modules. It is not uncommon to encounter a situation where you must recursively iterate through multiple levels, potentially returning results at each level. There are several important classes and libraries available that can help:
- Google Collections - Ignition includes access to the very useful Google Collections package that includes a set of classes that can help when working with iterators. The
Iterators
class, in particular, has functions for concatenating iterators and more that are very useful. - Ignition's
SearchObjectAggregator
andSearchObjectCursor
classes - These incredibly useful classes can be used to overcome the difficulty mentioned above. TheSearchObjectCursor
is an adaptation of Iterator that can returnSearchObjects
or otherSearchObjectCursors
. TheSearchObjectAggregator
is an implementation ofIterator
that knows how to deal with theSearchObjectCursor
. In other words, if you implementSearchObjectCursor
, you can return either results or new cursors to search, and the aggregator will sort it out for you