Accessing Objects Through Iterators
The OpenDoc class library implements over ten iterator classes, which you can use to access collections of OpenDoc objects such as facets, windows, and drag items. In addition, OpenDoc defines the interface for an iterator that you must subclass in all cases (ODEmbeddedFramesIterator), and one that you must subclass only if you create a focus module for a nonexclusive focus (ODFocusOwnerIterator).All OpenDoc iterator classes share certain characteristics, and you can use them all in a similar fashion. The iterators that you implement should also function in the same manner. For example, all iterators have at least these three methods:
Some iterators also have these methods:
First- Begins the iteration: sets your position to the first element in the collection and returns the element at that position.
Next- Advances your position in the collection by 1 and returns the element at your new position.
IsNotComplete- Returns
kODTrueif the element at your current position is valid; returnskODFalseif your current position is beyond the last element in the collection.
For most iterators, the
Last- Returns the final element in the collection.
Previous- Returns the element in the collection prior to the one at your current position.
FirstandNextmethods return their collection items as function results; for some, the collection items are returned in output parameters.Some iterators allow you to traverse the collection in either direction (beginning to end or end to beginning). For those iterators, the direction is an invariant; once the iteration has begun, you can't change direction. If you are traversing the collection from the beginning to the end, you call
Firstfollowed by a series of calls toNext; in this case you cannot callPrevious. If you are traversing the collection from the end to the beginning, you callLastfollowed by a series of calls toPrevious; in this case you cannot callNext.You can set up an iteration in several ways. A common method is to set up a
forloop that uses theIsNotCompletemethod to test for completion.
ODFrameFacetIterator* iter = frame->CreateFacetIterator(ev); for (ODFacet* facet = iter->First(ev); iter->IsNotComplete(ev); facet = iter->Next(ev)) { //...perform the task of the iteration }Alternatively, you can use awhilestatement to test for completion.
ODFrameFacetIterator* iter = frame->CreateFacetIterator(ev); ODFacet* facet = iter->First() while (iter->IsNotComplete()) { //...perform the task of the iteration facet = iter->Next(ev); }A third possibility--if theNextmethod returns its item as a function result and if it consistently returns a null value for a nonexistent element--is to use that method itself to test for completion.
ODFrameFacetIterator* iter = frame->CreateFacetIterator(ev); while ((facet = iter->Next(ev)) != kODNULL) { //...perform the task of the iteration }OpenDoc iterators follow these conventions:
- You can call
Nextwithout first callingFirst. If you do, your first call toNextis the same as a call toFirst.- You must call either
FirstorNextbefore callingIsNotComplete. If you do not,IsNotCompletegenerates the exceptionkODErrIteratorNotInitialized.- For an empty collection,
FirstandNextreturnkODNULL(if that type of iteration returns its information in the function result), andIsNotCompletereturnskODFalse.- If
IsNotCompletereturnskODTrue, the last item obtained is valid.- If
IsNotCompletereturnskODFalse(at the end of the iteration), a subsequent call toNextreturnskODNULL(if that type of iteration can return null values).- If the collection is modified while an iteration is in progress, calling any of these iterator methods generates the exception
kODErrIteratorOutOfSync.