API 0.9.5
AppKit/CPSearchField.j
Go to the documentation of this file.
00001 /*
00002  * CPSearchField.j
00003  * AppKit
00004  *
00005  * Created by cacaodev.
00006  * Copyright 2009.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 CPSearchFieldRecentsTitleMenuItemTag    = 1000;
00025 CPSearchFieldRecentsMenuItemTag         = 1001;
00026 CPSearchFieldClearRecentsMenuItemTag    = 1002;
00027 CPSearchFieldNoRecentsMenuItemTag       = 1003;
00028 
00029 var CPSearchFieldSearchImage = nil,
00030     CPSearchFieldFindImage = nil,
00031     CPSearchFieldCancelImage = nil,
00032     CPSearchFieldCancelPressedImage = nil;
00033 
00034 var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
00035     CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
00036     BUTTON_DEFAULT_HEIGHT = 22.0;
00037 
00038 var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
00039 
00040 var RECENT_SEARCH_PREFIX = @"   ";
00041 
00049 @implementation CPSearchField : CPTextField
00050 {
00051     CPButton    _searchButton;
00052     CPButton    _cancelButton;
00053     CPMenu      _searchMenuTemplate;
00054     CPMenu      _searchMenu;
00055 
00056     CPString    _recentsAutosaveName;
00057     CPArray     _recentSearches;
00058 
00059     int         _maximumRecents;
00060     BOOL        _sendsWholeSearchString;
00061     BOOL        _sendsSearchStringImmediately;
00062     BOOL        _canResignFirstResponder;
00063     CPTimer     _partialStringTimer;
00064 }
00065 
00066 + (CPString)defaultThemeClass
00067 {
00068     return @"searchfield"
00069 }
00070 
00071 + (void)initialize
00072 {
00073     if (self != [CPSearchField class])
00074         return;
00075 
00076     var bundle = [CPBundle bundleForClass:self];
00077     CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
00078     CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
00079     CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
00080     CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
00081 }
00082 
00083 - (id)initWithFrame:(CGRect)frame
00084 {
00085     if (self = [super initWithFrame:frame])
00086     {
00087         _maximumRecents = 10;
00088         _sendsWholeSearchString = NO;
00089         _sendsSearchStringImmediately = NO;
00090         _recentsAutosaveName = nil;
00091 
00092         [self _init];
00093 #if PLATFORM(DOM)
00094         _cancelButton._DOMElement.style.cursor = "default";
00095         _searchButton._DOMElement.style.cursor = "default";
00096 #endif
00097     }
00098 
00099     return self;
00100 }
00101 
00102 - (void)_init
00103 {
00104     _recentSearches = [CPArray array];
00105 
00106     [self setBezeled:YES];
00107     [self setBezelStyle:CPTextFieldRoundedBezel];
00108     [self setBordered:YES];
00109     [self setEditable:YES];
00110     [self setContinuous:YES];
00111 
00112     var bounds = [self bounds],
00113         cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]],
00114         searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
00115 
00116     [self setCancelButton:cancelButton];
00117     [self resetCancelButton];
00118 
00119     [self setSearchButton:searchButton];
00120     [self resetSearchButton];
00121 
00122     _canResignFirstResponder = YES;
00123 }
00124 
00125 - (void)viewWillMoveToSuperview:(CPView)aView
00126 {
00127     [super viewWillMoveToSuperview:aView];
00128 
00129     // First we remove any observer that may have been in place to avoid memory leakage.
00130     [[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:self];
00131 
00132     // Register the observe here if we need to.
00133     if (aView)
00134         [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
00135 }
00136 
00137 // Managing Buttons
00142 - (void)setSearchButton:(CPButton)button
00143 {
00144     if (button != _searchButton)
00145     {
00146         [_searchButton removeFromSuperview];
00147         _searchButton = button;
00148 
00149         [_searchButton setFrame:[self searchButtonRectForBounds:[self bounds]]];
00150         [_searchButton setAutoresizingMask:CPViewMaxXMargin];
00151         [self addSubview:_searchButton];
00152     }
00153 }
00154 
00159 - (CPButton)searchButton
00160 {
00161     return _searchButton;
00162 }
00163 
00168 - (void)resetSearchButton
00169 {
00170     var button = [self searchButton],
00171         searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
00172 
00173     [button setBordered:NO];
00174     [button setImageScaling:CPScaleToFit];
00175     [button setImage:searchButtonImage];
00176     [button setAutoresizingMask:CPViewMaxXMargin];
00177 }
00178 
00183 - (void)setCancelButton:(CPButton)button
00184 {
00185     if (button != _cancelButton)
00186     {
00187         [_cancelButton removeFromSuperview];
00188         _cancelButton = button;
00189 
00190         [_cancelButton setFrame:[self cancelButtonRectForBounds:[self bounds]]];
00191         [_cancelButton setAutoresizingMask:CPViewMinXMargin];
00192         [_cancelButton setTarget:self];
00193         [_cancelButton setAction:@selector(cancelOperation:)];
00194         [self _updateCancelButtonVisibility];
00195         [self addSubview:_cancelButton];
00196     }
00197 }
00198 
00203 - (CPButton)cancelButton
00204 {
00205     return _cancelButton;
00206 }
00207 
00212 - (void)resetCancelButton
00213 {
00214     var button = [self cancelButton];
00215     [button setBordered:NO];
00216     [button setImageScaling:CPScaleToFit];
00217     [button setImage:CPSearchFieldCancelImage];
00218     [button setAlternateImage:CPSearchFieldCancelPressedImage];
00219     [button setAutoresizingMask:CPViewMinXMargin];
00220     [button setTarget:self];
00221     [button setAction:@selector(cancelOperation:)];
00222 }
00223 
00224 // Custom Layout
00231 - (CGRect)searchTextRectForBounds:(CGRect)rect
00232 {
00233     var leftOffset = 0,
00234         width = _CGRectGetWidth(rect),
00235         bounds = [self bounds];
00236 
00237     if (_searchButton)
00238     {
00239         var searchBounds = [self searchButtonRectForBounds:bounds];
00240         leftOffset = _CGRectGetMaxX(searchBounds) + 2;
00241     }
00242 
00243     if (_cancelButton)
00244     {
00245         var cancelRect = [self cancelButtonRectForBounds:bounds];
00246         width = _CGRectGetMinX(cancelRect) - leftOffset;
00247     }
00248 
00249     return _CGRectMake(leftOffset, _CGRectGetMinY(rect), width, _CGRectGetHeight(rect));
00250 }
00251 
00257 - (CGRect)searchButtonRectForBounds:(CGRect)rect
00258 {
00259     return _CGRectMake(5, (_CGRectGetHeight(rect) - BUTTON_DEFAULT_HEIGHT) / 2, SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT);
00260 }
00261 
00267 - (CGRect)cancelButtonRectForBounds:(CGRect)rect
00268 {
00269     return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
00270 }
00271 
00272 // Managing Menu Templates
00277 - (CPMenu)searchMenuTemplate
00278 {
00279     return _searchMenuTemplate;
00280 }
00281 
00287 - (void)setSearchMenuTemplate:(CPMenu)aMenu
00288 {
00289     _searchMenuTemplate = aMenu;
00290 
00291     [self resetSearchButton];
00292     [self _loadRecentSearchList];
00293     [self _updateSearchMenu];
00294 }
00295 
00296 // Managing Search Modes
00301 - (BOOL)sendsWholeSearchString
00302 {
00303     return _sendsWholeSearchString;
00304 }
00305 
00310 - (void)setSendsWholeSearchString:(BOOL)flag
00311 {
00312     _sendsWholeSearchString = flag;
00313 }
00314 
00319 - (BOOL)sendsSearchStringImmediately
00320 {
00321     return _sendsSearchStringImmediately;
00322 }
00323 
00328 - (void)setSendsSearchStringImmediately:(BOOL)flag
00329 {
00330     _sendsSearchStringImmediately = flag;
00331 }
00332 
00333 // Managing Recent Search Strings
00338 - (int)maximumRecents
00339 {
00340     return _maximumRecents;
00341 }
00342 
00347 - (void)setMaximumRecents:(int)max
00348 {
00349     if (max > 254)
00350         max = 254;
00351     else if (max < 0)
00352         max = 10;
00353 
00354     _maximumRecents = max;
00355 }
00356 
00361 - (CPArray)recentSearches
00362 {
00363     return _recentSearches;
00364 }
00365 
00371 - (void)setRecentSearches:(CPArray)searches
00372 {
00373     var max = MIN([self maximumRecents], [searches count]),
00374         searches = [searches subarrayWithRange:CPMakeRange(0, max)];
00375 
00376     _recentSearches = searches;
00377     [self _autosaveRecentSearchList];
00378 }
00379 
00384 - (CPString)recentsAutosaveName
00385 {
00386     return _recentsAutosaveName;
00387 }
00388 
00393 - (void)setRecentsAutosaveName:(CPString)name
00394 {
00395     if (_recentsAutosaveName != nil)
00396         [self _deregisterForAutosaveNotification];
00397 
00398     _recentsAutosaveName = name;
00399 
00400     if (_recentsAutosaveName != nil)
00401       [self _registerForAutosaveNotification];
00402 }
00403 
00404 // Private methods and subclassing
00405 
00406 - (CGRect)contentRectForBounds:(CGRect)bounds
00407 {
00408     var superbounds = [super contentRectForBounds:bounds];
00409     return [self searchTextRectForBounds:superbounds];
00410 }
00411 
00412 + (double)_keyboardDelayForPartialSearchString:(CPString)string
00413 {
00414     return (6 - MIN([string length], 4)) / 10;
00415 }
00416 
00417 - (CPMenu)menu
00418 {
00419     return _searchMenu;
00420 }
00421 
00422 - (BOOL)isOpaque
00423 {
00424   return [super isOpaque] && [_cancelButton isOpaque] && [_searchButton isOpaque];
00425 }
00426 
00427 - (void)_updateCancelButtonVisibility
00428 {
00429     [_cancelButton setHidden:([[self stringValue] length] === 0)];
00430 }
00431 
00432 - (void)_searchFieldTextDidChange:(CPNotification)aNotification
00433 {
00434     if (![self sendsWholeSearchString])
00435     {
00436         if ([self sendsSearchStringImmediately])
00437             [self _sendPartialString];
00438         else
00439         {
00440             [_partialStringTimer invalidate];
00441             var timeInterval = [CPSearchField _keyboardDelayForPartialSearchString:[self stringValue]];
00442 
00443             _partialStringTimer = [CPTimer scheduledTimerWithTimeInterval:timeInterval
00444                                                                    target:self
00445                                                                  selector:@selector(_sendPartialString)
00446                                                                  userInfo:nil
00447                                                                   repeats:NO];
00448         }
00449     }
00450 
00451     [self _updateCancelButtonVisibility];
00452 }
00453 
00454 - (void)_sendAction:(id)sender
00455 {
00456     [self sendAction:[self action] to:[self target]];
00457 }
00458 
00459 - (void)sendAction:(SEL)anAction to:(id)anObject
00460 {
00461     [super sendAction:anAction to:anObject];
00462 
00463     [_partialStringTimer invalidate];
00464 
00465     [self _addStringToRecentSearches:[self stringValue]];
00466     [self _updateCancelButtonVisibility];
00467 }
00468 
00469 - (void)_addStringToRecentSearches:(CPString)string
00470 {
00471     if (string === nil || string === @"" || [_recentSearches containsObject:string])
00472         return;
00473 
00474     var searches = [CPMutableArray arrayWithArray:_recentSearches];
00475     [searches addObject:string];
00476     [self setRecentSearches:searches];
00477     [self _updateSearchMenu];
00478 }
00479 
00480 - (CPView)hitTest:(CGPoint)aPoint
00481 {
00482     // Make sure a hit anywhere within the search field returns the search field itself
00483     if (_CGRectContainsPoint([self frame], aPoint))
00484         return self;
00485     else
00486         return nil;
00487 }
00488 
00489 - (BOOL)resignFirstResponder
00490 {
00491     return _canResignFirstResponder && [super resignFirstResponder];
00492 }
00493 
00494 - (void)mouseDown:(CPEvent)anEvent
00495 {
00496     var location = [anEvent locationInWindow],
00497         point = [self convertPoint:location fromView:nil];
00498 
00499     if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
00500     {
00501         if (_searchMenuTemplate == nil)
00502             [self _sendAction:self];
00503         else
00504            [self _showMenu];
00505     }
00506     else if (_CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
00507         [_cancelButton mouseDown:anEvent];
00508     else
00509         [super mouseDown:anEvent];
00510 }
00511 
00545 - (CPMenu)defaultSearchMenuTemplate
00546 {
00547     var template = [[CPMenu alloc] init],
00548         item;
00549 
00550     item = [[CPMenuItem alloc] initWithTitle:@"Recent Searches"
00551                                       action:nil
00552                                keyEquivalent:@""];
00553     [item setTag:CPSearchFieldRecentsTitleMenuItemTag];
00554     [item setEnabled:NO];
00555     [template addItem:item];
00556 
00557     item = [[CPMenuItem alloc] initWithTitle:@"Recent search item"
00558                                       action:@selector(_searchFieldSearch:)
00559                                keyEquivalent:@""];
00560     [item setTag:CPSearchFieldRecentsMenuItemTag];
00561     [item setTarget:self];
00562     [template addItem:item];
00563 
00564     item = [[CPMenuItem alloc] initWithTitle:@"Clear Recent Searches"
00565                                       action:@selector(_searchFieldClearRecents:)
00566                                keyEquivalent:@""];
00567     [item setTag:CPSearchFieldClearRecentsMenuItemTag];
00568     [item setTarget:self];
00569     [template addItem:item];
00570 
00571     item = [[CPMenuItem alloc] initWithTitle:@"No Recent Searches"
00572                                       action:nil
00573                                keyEquivalent:@""];
00574     [item setTag:CPSearchFieldNoRecentsMenuItemTag];
00575     [item setEnabled:NO];
00576     [template addItem:item];
00577 
00578     return template;
00579 }
00580 
00581 - (void)_updateSearchMenu
00582 {
00583     if (_searchMenuTemplate === nil)
00584         return;
00585 
00586     var menu = [[CPMenu alloc] init],
00587         countOfRecents = [_recentSearches count],
00588         numberOfItems = [_searchMenuTemplate numberOfItems];
00589 
00590     for (var i = 0; i < numberOfItems; i++)
00591     {
00592         var item = [[_searchMenuTemplate itemAtIndex:i] copy];
00593 
00594         switch ([item tag])
00595         {
00596             case CPSearchFieldRecentsTitleMenuItemTag:
00597                 if (countOfRecents === 0)
00598                     continue;
00599 
00600                 if ([menu numberOfItems] > 0)
00601                     [self _addSeparatorToMenu:menu];
00602                 break;
00603 
00604             case CPSearchFieldRecentsMenuItemTag:
00605             {
00606                 var itemAction = @selector(_searchFieldSearch:);
00607 
00608                 for (var recentIndex = 0; recentIndex < countOfRecents; ++recentIndex)
00609                 {
00610                     // RECENT_SEARCH_PREFIX is a hack until CPMenuItem -setIndentationLevel works
00611                     var recentItem = [[CPMenuItem alloc] initWithTitle:RECENT_SEARCH_PREFIX + [_recentSearches objectAtIndex:recentIndex]
00612                                                                  action:itemAction
00613                                                           keyEquivalent:[item keyEquivalent]];
00614                     [item setTarget:self];
00615                     [menu addItem:recentItem];
00616                 }
00617 
00618                 continue;
00619             }
00620 
00621             case CPSearchFieldClearRecentsMenuItemTag:
00622                 if (countOfRecents === 0)
00623                     continue;
00624 
00625                 if ([menu numberOfItems] > 0)
00626                     [self _addSeparatorToMenu:menu];
00627 
00628                 [item setAction:@selector(_searchFieldClearRecents:)];
00629                 [item setTarget:self];
00630                 break;
00631 
00632             case CPSearchFieldNoRecentsMenuItemTag:
00633                 if (countOfRecents !== 0)
00634                     continue;
00635 
00636                 if ([menu numberOfItems] > 0)
00637                     [self _addSeparatorToMenu:menu];
00638                 break;
00639             }
00640 
00641         [item setEnabled:([item isEnabled] && [item action] != nil && [item target] != nil)];
00642         [menu addItem:item];
00643     }
00644 
00645     [menu setDelegate:self];
00646 
00647     _searchMenu = menu;
00648 }
00649 
00650 - (void)_addSeparatorToMenu:(CPMenu)aMenu
00651 {
00652     var separator = [CPMenuItem separatorItem];
00653     [separator setEnabled:NO];
00654     [aMenu addItem:separator];
00655 }
00656 
00657 - (void)menuWillOpen:(CPMenu)menu
00658 {
00659     _canResignFirstResponder = NO;
00660 }
00661 
00662 - (void)menuDidClose:(CPMenu)menu
00663 {
00664     _canResignFirstResponder = YES;
00665 
00666     [self becomeFirstResponder];
00667 }
00668 
00669 - (void)_showMenu
00670 {
00671     if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
00672         return;
00673 
00674     var aFrame = [[self superview] convertRect:[self frame] toView:nil],
00675         location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
00676 
00677     var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
00678 
00679     [self selectAll:nil];
00680     [CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:self];
00681 }
00682 
00683 - (void)_sendPartialString
00684 {
00685     [super sendAction:[self action] to:[self target]];
00686     [_partialStringTimer invalidate];
00687 }
00688 
00689 - (void)cancelOperation:(id)sender
00690 {
00691     [self setObjectValue:@""];
00692     [self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
00693 
00694     [self _updateCancelButtonVisibility];
00695 }
00696 
00697 - (void)_searchFieldSearch:(id)sender
00698 {
00699     var searchString = [[sender title] substringFromIndex:[RECENT_SEARCH_PREFIX length]];
00700 
00701     if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
00702         [self _addStringToRecentSearches:searchString];
00703 
00704     [self setObjectValue:searchString];
00705     [self _sendPartialString];
00706     [self selectAll:nil];
00707 
00708     [self _updateCancelButtonVisibility];
00709 }
00710 
00711 - (void)_searchFieldClearRecents:(id)sender
00712 {
00713     [self setRecentSearches:[CPArray array]];
00714     [self _updateSearchMenu];
00715     [self setStringValue:@""];
00716     [self _updateCancelButtonVisibility];
00717  }
00718 
00719 - (void)_registerForAutosaveNotification
00720 {
00721     [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateAutosavedRecents:) name:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
00722 }
00723 
00724 - (void)_deregisterForAutosaveNotification
00725 {
00726     [[CPNotificationCenter defaultCenter] removeObserver:self name:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
00727 }
00728 
00729 - (void)_autosaveRecentSearchList
00730 {
00731     if (_recentsAutosaveName != nil)
00732         [[CPNotificationCenter defaultCenter] postNotificationName:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
00733 }
00734 
00735 - (void)_updateAutosavedRecents:(id)notification
00736 {
00737     var name = [notification object];
00738     [[CPUserDefaults standardUserDefaults] setObject:_recentSearches forKey:name];
00739 }
00740 
00741 - (void)_loadRecentSearchList
00742 {
00743     var name = [self recentsAutosaveName];
00744     if (name === nil)
00745         return;
00746 
00747     var list = [[CPUserDefaults standardUserDefaults] objectForKey:name];
00748 
00749     if (list !== nil)
00750         _recentSearches = list;
00751 }
00752 
00753 @end
00754 
00755 var CPRecentsAutosaveNameKey            = @"CPRecentsAutosaveNameKey",
00756     CPSendsWholeSearchStringKey         = @"CPSendsWholeSearchStringKey",
00757     CPSendsSearchStringImmediatelyKey   = @"CPSendsSearchStringImmediatelyKey",
00758     CPMaximumRecentsKey                 = @"CPMaximumRecentsKey",
00759     CPSearchMenuTemplateKey             = @"CPSearchMenuTemplateKey";
00760 
00761 @implementation CPSearchField (CPCoding)
00762 
00763 - (void)encodeWithCoder:(CPCoder)coder
00764 {
00765     [_searchButton removeFromSuperview];
00766     [_cancelButton removeFromSuperview];
00767 
00768     [super encodeWithCoder:coder];
00769 
00770     if (_searchButton)
00771         [self addSubview:_searchButton];
00772     if (_cancelButton)
00773         [self addSubview:_cancelButton];
00774 
00775     [coder encodeBool:_sendsWholeSearchString forKey:CPSendsWholeSearchStringKey];
00776     [coder encodeBool:_sendsSearchStringImmediately forKey:CPSendsSearchStringImmediatelyKey];
00777     [coder encodeInt:_maximumRecents forKey:CPMaximumRecentsKey];
00778 
00779     if (_recentsAutosaveName)
00780         [coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
00781 
00782     if (_searchMenuTemplate)
00783         [coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
00784 }
00785 
00786 - (id)initWithCoder:(CPCoder)coder
00787 {
00788     if (self = [super initWithCoder:coder])
00789     {
00790         [self setRecentsAutosaveName:[coder decodeObjectForKey:CPRecentsAutosaveNameKey]];
00791         _sendsWholeSearchString   = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
00792         _sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
00793         _maximumRecents           = [coder decodeIntForKey:CPMaximumRecentsKey];
00794 
00795         var template              = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
00796 
00797         if (template)
00798             [self setSearchMenuTemplate:template];
00799 
00800         [self _init];
00801     }
00802 
00803     return self;
00804 }
00805 
00806 @end
 All Classes Files Functions Variables Defines