Revision: 11498
          http://bibdesk.svn.sourceforge.net/bibdesk/?rev=11498&view=rev
Author:   hofman
Date:     2007-11-09 06:11:25 -0800 (Fri, 09 Nov 2007)

Log Message:
-----------
Allow folders and separators in search bookmarks.

Modified Paths:
--------------
    trunk/bibdesk/BDSKAppController.m
    trunk/bibdesk/BDSKSearchBookmarkController.h
    trunk/bibdesk/BDSKSearchBookmarkController.m
    trunk/bibdesk/BibDocument_Groups.m
    trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj
    trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/classes.nib
    trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/keyedobjects.nib
    trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/classes.nib
    trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/keyedobjects.nib

Added Paths:
-----------
    trunk/bibdesk/Images/NewFolder.tiff
    trunk/bibdesk/Images/NewSeparator.tiff
    trunk/bibdesk/Images/SmallFolder.tiff
    trunk/bibdesk/Images/SmallMenu.tiff

Modified: trunk/bibdesk/BDSKAppController.m
===================================================================
--- trunk/bibdesk/BDSKAppController.m   2007-11-09 06:45:36 UTC (rev 11497)
+++ trunk/bibdesk/BDSKAppController.m   2007-11-09 14:11:25 UTC (rev 11498)
@@ -527,6 +527,29 @@
 // implemented in order to prevent the Copy As > Template menu from being 
updated at every key event
 - (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event 
target:(id *)target action:(SEL *)action { return NO; }
 
+- (void)addMenuItemsForBookmarks:(NSArray *)bookmarks toMenu:(NSMenu *)menu {
+    int i, iMax = [bookmarks count];
+    for (i = 0; i < iMax; i++) {
+        BDSKSearchBookmark *bm = [bookmarks objectAtIndex:i];
+        if ([bm bookmarkType] == BDSKSearchBookmarkTypeFolder) {
+            NSString *label = [bm label];
+            NSMenu *submenu = [[[NSMenu allocWithZone:[NSMenu menuZone]] 
initWithTitle:[bm label]] autorelease];
+            NSMenuItem *item = [menu addItemWithTitle:label ? label : @"" 
action:NULL keyEquivalent:@""];
+            [item setImage:[bm icon]];
+            [item setSubmenu:submenu];
+            [self addMenuItemsForBookmarks:[bm children] toMenu:submenu];
+        } else if ([bm bookmarkType] == BDSKSearchBookmarkTypeSeparator) {
+            [menu addItem:[NSMenuItem separatorItem]];
+        } else {
+            NSString *label = [bm label];
+            NSMenuItem *item = [menu addItemWithTitle:label ? label : @"" 
action:@selector(newSearchGroupFromBookmark:)  keyEquivalent:@""];
+            [item setTarget:self];
+            [item setRepresentedObject:[bm info]];
+            [item setImage:[bm icon]];
+        }
+    }
+}
+
 - (void)menuNeedsUpdate:(NSMenu *)menu {
     
     if ([menu isEqual:columnsMenu]) {
@@ -557,17 +580,13 @@
         
     } else if ([menu isEqual:searchBookmarksMenu]) {
         
-        BDSKSearchBookmarkController *bmController = 
[BDSKSearchBookmarkController sharedBookmarkController];
-        int i = [menu numberOfItems], iMax = [bmController countOfBookmarks];
+        NSArray *bookmarks = [[BDSKSearchBookmarkController 
sharedBookmarkController] bookmarks];
+        int i = [menu numberOfItems];
         while (--i > 2)
             [menu removeItemAtIndex:i];
-        if (iMax > 0)
+        if ([bookmarks count] > 0)
             [menu addItem:[NSMenuItem separatorItem]];
-        for (i = 0; i < iMax; i++) {
-            BDSKSearchBookmark *bm = [bmController objectInBookmarksAtIndex:i];
-            NSMenuItem *item = [menu addItemWithTitle:[bm label] 
action:@selector(newSearchGroupFromBookmark:)  keyEquivalent:@""];
-            [item setRepresentedObject:[bm info]];
-        }
+        [self addMenuItemsForBookmarks:bookmarks toMenu:menu];
         
     }
 }

Modified: trunk/bibdesk/BDSKSearchBookmarkController.h
===================================================================
--- trunk/bibdesk/BDSKSearchBookmarkController.h        2007-11-09 06:45:36 UTC 
(rev 11497)
+++ trunk/bibdesk/BDSKSearchBookmarkController.h        2007-11-09 14:11:25 UTC 
(rev 11498)
@@ -39,9 +39,19 @@
 #import <Cocoa/Cocoa.h>
 
 
+enum {
+    BDSKSearchBookmarkTypeBookmark,
+    BDSKSearchBookmarkTypeFolder,
+    BDSKSearchBookmarkTypeSeparator
+};
+
[EMAIL PROTECTED] BDSKSearchBookmark;
+
 @interface BDSKSearchBookmarkController : NSWindowController {
-    IBOutlet NSTableView *tableView;
+    IBOutlet NSOutlineView *outlineView;
     NSMutableArray *bookmarks;
+    NSArray *draggedBookmarks;
+    NSMutableDictionary *toolbarItems;
     NSUndoManager *undoManager;
 }
 
@@ -54,29 +64,60 @@
 - (void)insertObject:(id)obj inBookmarksAtIndex:(unsigned)index;
 - (void)removeObjectFromBookmarksAtIndex:(unsigned)index;
 
-- (void)addBookmarkWithInfo:(NSDictionary *)info label:(NSString *)label;
+- (void)addBookmarkWithInfo:(NSDictionary *)info label:(NSString *)label 
toFolder:(BDSKSearchBookmark *)folder;
 
+- (IBAction)insertBookmarkFolder:(id)sender;
+- (IBAction)insertBookmarkSeparator:(id)sender;
+- (IBAction)deleteBookmark:(id)sender;
+
 - (void)saveBookmarks;
 - (void)handleSearchBookmarkChangedNotification:(NSNotification *)notification;
+- (void)handleSearchBookmarkWillBeRemovedNotification:(NSNotification 
*)notification;
 
 - (NSUndoManager *)undoManager;
 
+- (void)setupToolbar;
+
 @end
 
 
 @interface BDSKSearchBookmark : NSObject <NSCopying> {
     NSString *label;
     NSDictionary *info;
+    NSMutableArray *children;
+    BDSKSearchBookmark *parent;
+    int bookmarkType;
 }
 
+- (id)initFolderWithChildren:(NSArray *)aChildren label:(NSString *)aLabel;
+- (id)initFolderWithLabel:(NSString *)aLabel;
+- (id)initSeparator;
 - (id)initWithInfo:(NSDictionary *)aDictionary label:(NSString *)aLabel;
 - (id)initWithDictionary:(NSDictionary *)dictionary;
 
 - (NSDictionary *)dictionaryValue;
 
+- (int)bookmarkType;
+
 - (NSDictionary *)info;
 
 - (NSString *)label;
 - (void)setLabel:(NSString *)newLabel;
 
+- (NSImage *)icon;
+
+- (BDSKSearchBookmark *)parent;
+- (void)setParent:(BDSKSearchBookmark *)newParent;
+- (NSArray *)children;
+- (void)insertChild:(BDSKSearchBookmark *)child atIndex:(unsigned int)index;
+- (void)addChild:(BDSKSearchBookmark *)child;
+- (void)removeChild:(BDSKSearchBookmark *)child;
+
+- (BOOL)isDescendantOf:(BDSKSearchBookmark *)bookmark;
+- (BOOL)isDescendantOfArray:(NSArray *)bookmarks;
+
 @end
+
+
[EMAIL PROTECTED] BDSKBookmarkOutlineView : NSOutlineView
[EMAIL PROTECTED]

Modified: trunk/bibdesk/BDSKSearchBookmarkController.m
===================================================================
--- trunk/bibdesk/BDSKSearchBookmarkController.m        2007-11-09 06:45:36 UTC 
(rev 11497)
+++ trunk/bibdesk/BDSKSearchBookmarkController.m        2007-11-09 14:11:25 UTC 
(rev 11498)
@@ -38,10 +38,25 @@
 
 #import "BDSKSearchBookmarkController.h"
 #import "BDSKStringConstants.h"
+#import "NSImage+Toolbox.h"
 
 static NSString *BDSKSearchBookmarkRowsPboardType = 
@"BDSKSearchBookmarkRowsPboardType";
 static NSString *BDSKSearchBookmarkChangedNotification = 
@"BDSKSearchBookmarkChangedNotification";
+static NSString *BDSKSearchBookmarkWillBeRemovedNotification = 
@"BDSKSearchBookmarkWillBeRemovedNotification";
 
+static NSString *BDSKSearchBookmarksToolbarIdentifier = 
@"BDSKSearchBookmarksToolbarIdentifier";
+static NSString *BDSKSearchBookmarksNewFolderToolbarItemIdentifier = 
@"BDSKSearchBookmarksNewFolderToolbarItemIdentifier";
+static NSString *BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier = 
@"BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier";
+static NSString *BDSKSearchBookmarksDeleteToolbarItemIdentifier = 
@"BDSKSearchBookmarksDeleteToolbarItemIdentifier";
+
+static NSString *BDSKSearchBookmarkTypeBookmarkString = @"bookmark";
+static NSString *BDSKSearchBookmarkTypeFolderString = @"folder";
+static NSString *BDSKSearchBookmarkTypeSeparatorString = @"separator";
+
+#define CHILDREN_KEY    @"children"
+#define LABEL_KEY       @"label"
+#define TYPE_KEY        @"type"
+
 @implementation BDSKSearchBookmarkController
 
 + (id)sharedBookmarkController {
@@ -67,6 +82,10 @@
                                                  
selector:@selector(handleSearchBookmarkChangedNotification:)
                                                      
name:BDSKSearchBookmarkChangedNotification
                                                    object:nil];
+               [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 
selector:@selector(handleSearchBookmarkWillBeDeletedNotification:)
+                                                     
name:BDSKSearchBookmarkWillBeRemovedNotification
+                                                   object:nil];
     }
     return self;
 }
@@ -80,8 +99,9 @@
 - (NSString *)windowNibName { return @"SearchBookmarksWindow"; }
 
 - (void)windowDidLoad {
+    [self setupToolbar];
     [self setWindowFrameAutosaveName:@"BDSKSearchBookmarksWindow"];
-    [tableView registerForDraggedTypes:[NSArray 
arrayWithObject:BDSKSearchBookmarkRowsPboardType]];
+    [outlineView registerForDraggedTypes:[NSArray 
arrayWithObject:BDSKSearchBookmarkRowsPboardType]];
 }
 
 - (NSArray *)bookmarks {
@@ -90,7 +110,7 @@
 
 - (void)setBookmarks:(NSArray *)newBookmarks {
     [[[self undoManager] prepareWithInvocationTarget:self] 
setBookmarks:[[bookmarks copy] autorelease]];
-    return [bookmarks setArray:newBookmarks];
+    [bookmarks setArray:newBookmarks];
 }
 
 - (unsigned)countOfBookmarks {
@@ -104,30 +124,140 @@
 - (void)insertObject:(id)obj inBookmarksAtIndex:(unsigned)idx {
     [[[self undoManager] prepareWithInvocationTarget:self] 
removeObjectFromBookmarksAtIndex:idx];
     [bookmarks insertObject:obj atIndex:idx];
-    [self saveBookmarks];
+    [self handleSearchBookmarkChangedNotification:nil];
 }
 
 - (void)removeObjectFromBookmarksAtIndex:(unsigned)idx {
     [[[self undoManager] prepareWithInvocationTarget:self] 
insertObject:[bookmarks objectAtIndex:idx] inBookmarksAtIndex:idx];
+    [self handleSearchBookmarkWillBeRemovedNotification:nil];
     [bookmarks removeObjectAtIndex:idx];
-    [self saveBookmarks];
+    [self handleSearchBookmarkChangedNotification:nil];
 }
 
-- (void)addBookmarkWithInfo:(NSDictionary *)info label:(NSString *)label {
+- (NSArray *)childrenOfBookmark:(BDSKSearchBookmark *)bookmark {
+    return bookmark ? [bookmark children] : bookmarks;
+}
+
+- (unsigned int)indexOfChildBookmark:(BDSKSearchBookmark *)bookmark {
+    return [[self childrenOfBookmark:[bookmark parent]] 
indexOfObject:bookmark];
+}
+
+- (void)bookmark:(BDSKSearchBookmark *)bookmark 
insertChildBookmark:(BDSKSearchBookmark *)child atIndex:(unsigned int)idx {
+    if (bookmark)
+        [bookmark insertChild:child atIndex:idx];
+    else
+        [self insertObject:child inBookmarksAtIndex:idx];
+}
+
+- (void)removeChildBookmark:(BDSKSearchBookmark *)bookmark {
+    BDSKSearchBookmark *parent = [bookmark parent];
+    if (parent)
+        [parent removeChild:bookmark];
+    else
+        [[self mutableArrayValueForKey:@"bookmarks"] removeObject:bookmark];
+}
+
+- (NSArray *)minimumCoverForBookmarks:(NSArray *)items {
+    NSEnumerator *bmEnum = [items objectEnumerator];
+    BDSKSearchBookmark *bm;
+    BDSKSearchBookmark *lastBm = nil;
+    NSMutableArray *minimalCover = [NSMutableArray array];
+    
+    while (bm = [bmEnum nextObject]) {
+        if ([bm isDescendantOf:lastBm] == NO) {
+            [minimalCover addObject:bm];
+            lastBm = bm;
+        }
+    }
+    return minimalCover;
+}
+
+- (void)addBookmarkWithInfo:(NSDictionary *)info label:(NSString *)label 
toFolder:(BDSKSearchBookmark *)folder {
     BDSKSearchBookmark *bookmark = [[BDSKSearchBookmark alloc] 
initWithInfo:info label:label];
-    [[self mutableArrayValueForKey:@"bookmarks"] addObject:bookmark];
-    [bookmark release];
+    if (bookmark) {
+        [self bookmark:folder insertChildBookmark:bookmark atIndex:[[self 
childrenOfBookmark:folder] count]];
+        [bookmark release];
+    }
 }
 
+- (NSArray *)draggedBookmarks {
+    return draggedBookmarks;
+}
+
+- (void)setDraggedBookmarks:(NSArray *)items {
+    if (draggedBookmarks != items) {
+        [draggedBookmarks release];
+        draggedBookmarks = [items retain];
+    }
+}
+
 - (void)saveBookmarks {
     [[OFPreferenceWrapper sharedPreferenceWrapper] setObject:[bookmarks 
valueForKey:@"dictionaryValue"] forKey:BDSKSearchGroupBookmarksKey];
 }
 
+#pragma mark Actions
+
+- (IBAction)insertBookmarkFolder:(id)sender {
+    BDSKSearchBookmark *folder = [[[BDSKSearchBookmark alloc] 
initFolderWithLabel:NSLocalizedString(@"Folder", @"default folder name")] 
autorelease];
+    int rowIndex = [[outlineView selectedRowIndexes] lastIndex];
+    BDSKSearchBookmark *item = nil;
+    unsigned int idx = [bookmarks count];
+    
+    if (rowIndex != NSNotFound) {
+        BDSKSearchBookmark *selectedItem = [outlineView itemAtRow:rowIndex];
+        if ([outlineView isItemExpanded:selectedItem]) {
+            item = selectedItem;
+            idx = [[item children] count];
+        } else {
+            item = [selectedItem parent];
+            idx = [self indexOfChildBookmark:selectedItem] + 1;
+        }
+    }
+    [self bookmark:item insertChildBookmark:folder atIndex:idx];
+    
+    int row = [outlineView rowForItem:folder];
+    [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] 
byExtendingSelection:NO];
+    [outlineView editColumn:0 row:row withEvent:nil select:YES];
+}
+
+- (IBAction)insertBookmarkSeparator:(id)sender {
+    BDSKSearchBookmark *separator = [[[BDSKSearchBookmark alloc] 
initSeparator] autorelease];
+    int rowIndex = [[outlineView selectedRowIndexes] lastIndex];
+    BDSKSearchBookmark *item = nil;
+    unsigned int idx = [bookmarks count];
+    
+    if (rowIndex != NSNotFound) {
+        BDSKSearchBookmark *selectedItem = [outlineView itemAtRow:rowIndex];
+        if ([outlineView isItemExpanded:selectedItem]) {
+            item = selectedItem;
+            idx = [[item children] count];
+        } else {
+            item = [selectedItem parent];
+            idx = [self indexOfChildBookmark:selectedItem] + 1;
+        }
+    }
+    [self bookmark:item insertChildBookmark:separator atIndex:idx];
+    
+    int row = [outlineView rowForItem:separator];
+    [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] 
byExtendingSelection:NO];
+}
+
+- (IBAction)deleteBookmark:(id)sender {
+    [outlineView delete:sender];
+}
+
+#pragma mark Notification handlers
+
+- (void)handleSearchBookmarkWillBeRemovedNotification:(NSNotification 
*)notification  {
+    if ([outlineView editedRow] && [[self window] 
makeFirstResponder:outlineView] == NO)
+        [[self window] endEditingFor:nil];
+}
+
 - (void)handleSearchBookmarkChangedNotification:(NSNotification *)notification 
{
     [self saveBookmarks];
+    [outlineView reloadData];
 }
 
-
 #pragma mark Undo support
 
 - (NSUndoManager *)undoManager {
@@ -140,54 +270,264 @@
     return [self undoManager];
 }
 
-#pragma mark tableView datasource methods
+#pragma mark NSOutlineView datasource methods
 
-- (int)numberOfRowsInTableView:(NSTableView *)tv { return 0; }
+- (int)outlineView:(NSOutlineView *)ov numberOfChildrenOfItem:(id)item {
+    return [[self childrenOfBookmark:item] count];
+}
 
-- (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn 
*)tableColumn row:(int)row { return nil; }
+- (BOOL)outlineView:(NSOutlineView *)ov isItemExpandable:(id)item {
+    return [item bookmarkType] == BDSKSearchBookmarkTypeFolder;
+}
 
-- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet 
*)rowIndexes toPasteboard:(NSPasteboard *)pboard {
-    OBASSERT([rowIndexes count] == 1);
+- (id)outlineView:(NSOutlineView *)ov child:(int)idx ofItem:(id)item {
+    return [[self childrenOfBookmark:item] objectAtIndex:idx];
+}
+
+- (id)outlineView:(NSOutlineView *)ov objectValueForTableColumn:(NSTableColumn 
*)tableColumn byItem:(id)item {
+    NSString *tcID = [tableColumn identifier];
+    NSDictionary *info = [item info];
+    if ([tcID isEqualToString:@"label"]) {
+        return [NSDictionary dictionaryWithObjectsAndKeys:[item label], 
OATextWithIconCellStringKey, [item icon], OATextWithIconCellImageKey, nil];
+    } else if ([tcID isEqualToString:@"server"]) {
+        [info valueForKey:@"name"];
+    } else if ([tcID isEqualToString:@"search term"]) {
+        [info valueForKey:@"search term"];
+    }
+    return nil;
+}
+
+- (void)outlineView:(NSOutlineView *)ov setObjectValue:(id)object 
forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
+    NSString *tcID = [tableColumn identifier];
+    if ([tcID isEqualToString:@"label"]) {
+        if (object == nil)
+            object = @"";
+        if ([object isEqualToString:[item label]] == NO)
+            [item setLabel:object];
+    }
+}
+
+- (BOOL)outlineView:(NSOutlineView *)ov writeItems:(NSArray *)items 
toPasteboard:(NSPasteboard *)pboard {
+    [self setDraggedBookmarks:[self minimumCoverForBookmarks:items]];
     [pboard declareTypes:[NSArray 
arrayWithObjects:BDSKSearchBookmarkRowsPboardType, nil] owner:nil];
-    [pboard setPropertyList:[NSNumber numberWithUnsignedInt:[rowIndexes 
firstIndex]] forType:BDSKSearchBookmarkRowsPboardType];
+    [pboard setData:[NSData data] forType:BDSKSearchBookmarkRowsPboardType];
     return YES;
 }
 
-- (NSDragOperation)tableView:(NSTableView *)tv validateDrop:(id 
<NSDraggingInfo>)info proposedRow:(int)row 
proposedDropOperation:(NSTableViewDropOperation)op {
+- (NSDragOperation)outlineView:(NSOutlineView *)ov validateDrop:(id 
<NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)idx {
     NSPasteboard *pboard = [info draggingPasteboard];
     NSString *type = [pboard availableTypeFromArray:[NSArray 
arrayWithObjects:BDSKSearchBookmarkRowsPboardType, nil]];
     
     if (type) {
-        [tv setDropRow:row == -1 ? [tv numberOfRows] : row 
dropOperation:NSTableViewDropAbove];
-        return NSDragOperationMove;
+        if (idx == NSOutlineViewDropOnItemIndex) {
+            if ([item bookmarkType] == BDSKSearchBookmarkTypeFolder && 
[outlineView isItemExpanded:item]) {
+                [ov setDropItem:item dropChildIndex:0];
+            } else if ([item parent]) {
+                [ov setDropItem:[item parent] dropChildIndex:[[[item parent] 
children] indexOfObject:item] + 1];
+            } else if (item) {
+                [ov setDropItem:nil dropChildIndex:[bookmarks 
indexOfObject:item] + 1];
+            } else {
+                [ov setDropItem:nil dropChildIndex:[bookmarks count]];
+            }
+        }
+        return [item isDescendantOfArray:[self draggedBookmarks]] ? 
NSDragOperationNone : NSDragOperationMove;
     }
     return NSDragOperationNone;
 }
 
-
-- (BOOL)tableView:(NSTableView *)tv acceptDrop:(id <NSDraggingInfo>)info 
row:(int)row dropOperation:(NSTableViewDropOperation)op {
+- (BOOL)outlineView:(NSOutlineView *)ov acceptDrop:(id <NSDraggingInfo>)info 
item:(id)item childIndex:(int)idx {
     NSPasteboard *pboard = [info draggingPasteboard];
     NSString *type = [pboard availableTypeFromArray:[NSArray 
arrayWithObjects:BDSKSearchBookmarkRowsPboardType, nil]];
     
     if (type) {
-        int draggedRow = [[pboard 
propertyListForType:BDSKSearchBookmarkRowsPboardType] intValue];
-        NSDictionary *bookmark = [[bookmarks objectAtIndex:draggedRow] retain];
-        [self removeObjectFromBookmarksAtIndex:draggedRow];
-        [self insertObject:bookmark inBookmarksAtIndex:row < draggedRow ? row 
: row - 1];
-        [bookmark release];
-        [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] 
byExtendingSelection:NO];
+        NSEnumerator *bmEnum = [[self draggedBookmarks] objectEnumerator];
+        BDSKSearchBookmark *bookmark;
+                               
+               while (bookmark = [bmEnum nextObject]) {
+            int bookmarkIndex = [self indexOfChildBookmark:bookmark];
+            if (item == [bookmark parent]) {
+                if (idx > bookmarkIndex)
+                    idx--;
+                if (idx == bookmarkIndex)
+                    continue;
+            }
+            [self removeChildBookmark:bookmark];
+            [self bookmark:item insertChildBookmark:bookmark atIndex:idx++];
+               }
         return YES;
     }
     return NO;
 }
 
+- (void)outlineView:(NSOutlineView *)ov 
dragEndedWithOperation:(NSDragOperation)operation {
+    [self setDraggedBookmarks:nil];
+}
+
+#pragma mark NSOutlineView delegate methods
+
+- (void)outlineView:(NSOutlineView *)ov willDisplayCell:(id)cell 
forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
+    if ([[tableColumn identifier] isEqualToString:@"file"]) {
+        if ([item bookmarkType] == BDSKSearchBookmarkTypeFolder)
+            [cell setTextColor:[NSColor disabledControlTextColor]];
+        else
+            [cell setTextColor:[NSColor controlTextColor]];
+    }
+}
+
+- (BOOL)outlineView:(NSOutlineView *)ov shouldEditTableColumn:(NSTableColumn 
*)tableColumn item:(id)item {
+    return [[tableColumn identifier] isEqualToString:@"label"] && [item 
bookmarkType] != BDSKSearchBookmarkTypeSeparator;
+}
+
+- (void)outlineView:(NSOutlineView *)ov deleteItems:(NSArray *)items {
+    NSEnumerator *itemEnum = [[self minimumCoverForBookmarks:items] 
reverseObjectEnumerator];
+    BDSKSearchBookmark *item;
+    while (item = [itemEnum  nextObject])
+        [self removeChildBookmark:item];
+}
+
+- (BOOL)outlineView:(NSOutlineView *)ov canDeleteItems:(NSArray *)items {
+    return [items count] > 0;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)ov drawSeparatorRowForItem:(id)item {
+    return [item bookmarkType] == BDSKSearchBookmarkTypeSeparator;
+}
+
+#pragma mark Toolbar
+
+- (void)setupToolbar {
+    // Create a new toolbar instance, and attach it to our document window
+    NSToolbar *toolbar = [[[NSToolbar alloc] 
initWithIdentifier:BDSKSearchBookmarksToolbarIdentifier] autorelease];
+    OAToolbarItem *item;
+    
+    toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:3];
+    
+    // Set up toolbar properties: Allow customization, give a default display 
mode, and remember state in user defaults
+    [toolbar setAllowsUserCustomization: YES];
+    [toolbar setAutosavesConfiguration: YES];
+    [toolbar setDisplayMode: NSToolbarDisplayModeDefault];
+    
+    // We are the delegate
+    [toolbar setDelegate: self];
+    
+    // Add template toolbar items
+    
+    item = [[OAToolbarItem alloc] 
initWithItemIdentifier:BDSKSearchBookmarksNewFolderToolbarItemIdentifier];
+    [item setLabel:NSLocalizedString(@"New Folder", @"Toolbar item label")];
+    [item setPaletteLabel:NSLocalizedString(@"New Folder", @"Toolbar item 
label")];
+    [item setToolTip:NSLocalizedString(@"Add a New Folder", @"Tool tip 
message")];
+    [item setImage:[NSImage imageNamed:@"NewFolder"]];
+    [item setTarget:self];
+    [item setAction:@selector(insertBookmarkFolder:)];
+    [toolbarItems setObject:item 
forKey:BDSKSearchBookmarksNewFolderToolbarItemIdentifier];
+    [item release];
+    
+    item = [[OAToolbarItem alloc] 
initWithItemIdentifier:BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier];
+    [item setLabel:NSLocalizedString(@"New Separator", @"Toolbar item label")];
+    [item setPaletteLabel:NSLocalizedString(@"New Separator", @"Toolbar item 
label")];
+    [item setToolTip:NSLocalizedString(@"Add a New Separator", @"Tool tip 
message")];
+    [item setImage:[NSImage imageNamed:@"NewSeparator"]];
+    [item setTarget:self];
+    [item setAction:@selector(insertBookmarkSeparator:)];
+    [toolbarItems setObject:item 
forKey:BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier];
+    [item release];
+    
+    item = [[OAToolbarItem alloc] 
initWithItemIdentifier:BDSKSearchBookmarksDeleteToolbarItemIdentifier];
+    [item setLabel:NSLocalizedString(@"Delete", @"Toolbar item label")];
+    [item setPaletteLabel:NSLocalizedString(@"Delete", @"Toolbar item label")];
+    [item setToolTip:NSLocalizedString(@"Delete Selected Items", @"Tool tip 
message")];
+    [item setImage:[NSImage 
imageWithLargeIconForToolboxCode:kToolbarDeleteIcon]];
+    [item setTarget:self];
+    [item setAction:@selector(deleteBookmark:)];
+    [toolbarItems setObject:item 
forKey:BDSKSearchBookmarksDeleteToolbarItemIdentifier];
+    [item release];
+    
+    // Attach the toolbar to the window
+    [[self window] setToolbar:toolbar];
+}
+
+- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar 
itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL) 
willBeInserted {
+
+    NSToolbarItem *item = [toolbarItems objectForKey:itemIdent];
+    NSToolbarItem *newItem = [[item copy] autorelease];
+    return newItem;
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
+    return [NSArray arrayWithObjects:
+        BDSKSearchBookmarksNewFolderToolbarItemIdentifier, 
+        BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier, 
+        BDSKSearchBookmarksDeleteToolbarItemIdentifier, nil];
+}
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
+    return [NSArray arrayWithObjects: 
+        BDSKSearchBookmarksNewFolderToolbarItemIdentifier, 
+        BDSKSearchBookmarksNewSeparatorToolbarItemIdentifier, 
+               BDSKSearchBookmarksDeleteToolbarItemIdentifier, 
+        NSToolbarFlexibleSpaceItemIdentifier, 
+               NSToolbarSpaceItemIdentifier, 
+               NSToolbarSeparatorItemIdentifier, 
+               NSToolbarCustomizeToolbarItemIdentifier, nil];
+}
+
+- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
+    NSString *identifier = [toolbarItem itemIdentifier];
+    if ([identifier 
isEqualToString:BDSKSearchBookmarksDeleteToolbarItemIdentifier]) {
+        return [outlineView numberOfSelectedRows] > 0;
+    } else {
+        return YES;
+    }
+}
+
 @end
 
+#pragma mark -
 
 @implementation BDSKSearchBookmark
 
++ (NSImage *)smallSearchBookmarkIcon {
+    static NSImage *smallSearchBookmarkIcon = nil;
+    if (smallSearchBookmarkIcon == nil) {
+        NSImage *image = [NSImage imageNamed:@"searchFolderIcon"];
+        NSRect rect = {NSZeroPoint, [image size]};
+        smallSearchBookmarkIcon = [[NSImage alloc] 
initWithSize:NSMakeSize(16.0, 16.0)];
+        [smallSearchBookmarkIcon lockFocus];
+        [[NSGraphicsContext currentContext] 
setImageInterpolation:NSImageInterpolationHigh];
+        [image drawInRect:NSMakeRect(0.0, 0.0, 16.0, 16.0) fromRect:rect 
operation:NSCompositeCopy fraction:1.0];
+        [smallSearchBookmarkIcon unlockFocus];
+    }
+    return smallSearchBookmarkIcon;
+}
+
+- (id)initFolderWithChildren:(NSArray *)aChildren label:(NSString *)aLabel {
+    if (self = [super init]) {
+        bookmarkType = BDSKSearchBookmarkTypeFolder;
+        info = nil;
+        label = [aLabel copy];
+        children = [aChildren mutableCopy];
+        [children makeObjectsPerformSelector:@selector(setParent:) 
withObject:self];
+    }
+    return self;
+}
+
+- (id)initFolderWithLabel:(NSString *)aLabel {
+    return [self initFolderWithChildren:[NSArray array] label:aLabel];
+}
+
+- (id)initSeparator {
+    if (self = [super init]) {
+        bookmarkType = BDSKSearchBookmarkTypeSeparator;
+        info = nil;
+        label = nil;
+        children = nil;
+    }
+    return self;
+}
+
 - (id)initWithInfo:(NSDictionary *)aDictionary label:(NSString *)aLabel {
     if (self = [super init]) {
+        bookmarkType = BDSKSearchBookmarkTypeBookmark;
         info = [aDictionary copy];
         label = [aLabel copy];
     }
@@ -200,27 +540,65 @@
 }
 
 - (id)initWithDictionary:(NSDictionary *)dictionary {
-    NSMutableDictionary *dict = [[dictionary mutableCopy] autorelease];
-    [dict removeObjectForKey:@"label"];
-    return [self initWithInfo:dict label:[dictionary objectForKey:@"label"]];
+    if ([[dictionary objectForKey:TYPE_KEY] 
isEqualToString:BDSKSearchBookmarkTypeFolderString]) {
+        NSEnumerator *dictEnum = [[dictionary objectForKey:CHILDREN_KEY] 
objectEnumerator];
+        NSDictionary *dict;
+        NSMutableArray *newChildren = [NSMutableArray array];
+        while (dict = [dictEnum nextObject])
+            [newChildren addObject:[[[[self class] alloc] 
initWithDictionary:dict] autorelease]];
+        return [self initFolderWithChildren:newChildren label:[dictionary 
objectForKey:LABEL_KEY]];
+    } else if ([[dictionary objectForKey:TYPE_KEY] 
isEqualToString:BDSKSearchBookmarkTypeSeparatorString]) {
+        return [self initSeparator];
+    } else {
+        NSMutableDictionary *dict = [[dictionary mutableCopy] autorelease];
+        [dict removeObjectForKey:@"label"];
+        return [self initWithInfo:dict label:[dictionary 
objectForKey:LABEL_KEY]];
+    }
 }
 
 - (id)copyWithZone:(NSZone *)aZone {
-    return [[[self class] allocWithZone:aZone] initWithInfo:info label:label];
+    if (bookmarkType == BDSKSearchBookmarkTypeFolder)
+        return [[[self class] allocWithZone:aZone] 
initFolderWithChildren:[[[NSArray alloc] initWithArray:children copyItems:YES] 
autorelease] label:label];
+    else if (bookmarkType == BDSKSearchBookmarkTypeSeparator)
+        return [[[self class] allocWithZone:aZone] initSeparator];
+    else
+        return [[[self class] allocWithZone:aZone] initWithInfo:info 
label:label];
 }
 
 - (void)dealloc {
+    [[[BDSKSearchBookmarkController sharedBookmarkController] undoManager] 
removeAllActionsWithTarget:self];
     [info release];
     [label release];
+    [children release];
     [super dealloc];
 }
 
+- (NSString *)description {
+    if (bookmarkType == BDSKSearchBookmarkTypeFolder)
+        return [NSString stringWithFormat:@"<%@: label=%@, children=%@>", 
[self class], label, children];
+    else if (bookmarkType == BDSKSearchBookmarkTypeSeparator)
+        return [NSString stringWithFormat:@"<%@: separator>", [self class]];
+    else
+        return [NSString stringWithFormat:@"<%@: label=%@, info=%@>", [self 
class], label, info];
+}
+
 - (NSDictionary *)dictionaryValue {
-    NSMutableDictionary *dictionary = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:label, @"label", nil];
-    [dictionary addEntriesFromDictionary:info];
+    NSMutableDictionary *dictionary = nil;
+    if (bookmarkType == BDSKSearchBookmarkTypeFolder) {
+        dictionary = [NSDictionary 
dictionaryWithObjectsAndKeys:BDSKSearchBookmarkTypeFolderString, TYPE_KEY, 
[children valueForKey:@"dictionaryValue"], CHILDREN_KEY, label, LABEL_KEY, nil];
+    } else if (bookmarkType == BDSKSearchBookmarkTypeSeparator) {
+        dictionary = [NSDictionary 
dictionaryWithObjectsAndKeys:BDSKSearchBookmarkTypeSeparatorString, TYPE_KEY, 
nil];
+    } else {
+        dictionary = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:BDSKSearchBookmarkTypeBookmarkString, TYPE_KEY, 
label, LABEL_KEY, nil];
+        [(NSMutableDictionary *)dictionary addEntriesFromDictionary:info];
+    }
     return dictionary;
 }
 
+- (int)bookmarkType {
+    return bookmarkType;
+}
+
 - (NSDictionary *)info {
     return info;
 }
@@ -239,4 +617,88 @@
     }
 }
 
+- (NSImage *)icon {
+    if ([self bookmarkType] == BDSKSearchBookmarkTypeFolder)
+        return [NSImage imageNamed:@"SmallFolder"];
+    else if (bookmarkType == BDSKSearchBookmarkTypeSeparator)
+        return nil;
+    else
+        return [[self class] smallSearchBookmarkIcon];
+}
+
+- (BDSKSearchBookmark *)parent {
+    return parent;
+}
+
+- (void)setParent:(BDSKSearchBookmark *)newParent {
+    parent = newParent;
+}
+
+- (NSArray *)children {
+    return children;
+}
+
+- (void)insertChild:(BDSKSearchBookmark *)child atIndex:(unsigned int)idx {
+    NSUndoManager *undoManager = [[BDSKSearchBookmarkController 
sharedBookmarkController] undoManager];
+    [(BDSKSearchBookmark *)[undoManager prepareWithInvocationTarget:self] 
removeChild:child];
+    [children insertObject:child atIndex:idx];
+    [child setParent:self];
+    [[NSNotificationCenter defaultCenter] 
postNotificationName:BDSKSearchBookmarkChangedNotification object:self];
+}
+
+- (void)addChild:(BDSKSearchBookmark *)child {
+    [self insertChild:child atIndex:[children count]];
+}
+
+- (void)removeChild:(BDSKSearchBookmark *)child {
+    NSUndoManager *undoManager = [[BDSKSearchBookmarkController 
sharedBookmarkController] undoManager];
+    [(BDSKSearchBookmark *)[undoManager prepareWithInvocationTarget:self] 
insertChild:child atIndex:[[self children] indexOfObject:child]];
+    [[NSNotificationCenter defaultCenter] 
postNotificationName:BDSKSearchBookmarkWillBeRemovedNotification object:self];
+    [child setParent:nil];
+    [children removeObject:child];
+    [[NSNotificationCenter defaultCenter] 
postNotificationName:BDSKSearchBookmarkChangedNotification object:self];
+}
+
+- (BOOL)isDescendantOf:(BDSKSearchBookmark *)bookmark {
+    if (self == bookmark)
+        return YES;
+    NSEnumerator *childEnum = [[bookmark children] objectEnumerator];
+    BDSKSearchBookmark *child;
+    while (child = [childEnum nextObject]) {
+        if ([self isDescendantOf:child])
+            return YES;
+    }
+    return NO;
+}
+
+- (BOOL)isDescendantOfArray:(NSArray *)bookmarks {
+    NSEnumerator *bmEnum = [bookmarks objectEnumerator];
+    BDSKSearchBookmark *bm = nil;
+    while (bm = [bmEnum nextObject]) {
+        if ([self isDescendantOf:bm]) return YES;
+    }
+    return NO;
+}
+
 @end
+
+#pragma mark -
+
[EMAIL PROTECTED] BDSKBookmarkOutlineView
+
+#define SEPARATOR_LEFT_INDENT 20.0
+#define SEPARATOR_RIGHT_INDENT 2.0
+
+- (void)drawRow:(int)rowIndex clipRect:(NSRect)clipRect {
+    if ([[self delegate] 
respondsToSelector:@selector(outlineView:drawSeparatorRowForItem:)] &&
+        [[self delegate] outlineView:self drawSeparatorRowForItem:[self 
itemAtRow:rowIndex]]) {
+        float indent = [self levelForItem:[self itemAtRow:rowIndex]] * [self 
indentationPerLevel];
+        NSRect rect = [self rectOfRow:rowIndex];
+        [[NSColor gridColor] setStroke];
+        [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMinX(rect) + indent + 
SEPARATOR_LEFT_INDENT, floorf(NSMidY(rect)) + 0.5) 
toPoint:NSMakePoint(NSMaxX(rect) - SEPARATOR_RIGHT_INDENT, floorf(NSMidY(rect)) 
+ 0.5)];
+    } else {
+        [super drawRow:rowIndex clipRect:clipRect];
+    }
+}
+
[EMAIL PROTECTED]

Modified: trunk/bibdesk/BibDocument_Groups.m
===================================================================
--- trunk/bibdesk/BibDocument_Groups.m  2007-11-09 06:45:36 UTC (rev 11497)
+++ trunk/bibdesk/BibDocument_Groups.m  2007-11-09 14:11:25 UTC (rev 11498)
@@ -1009,7 +1009,7 @@
 - (void)searchBookmarkSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode 
contextInfo:(void *)contextInfo {
     if (returnCode == NSOKButton) {
         BDSKGroup *group = [[self selectedGroups] lastObject];
-        [[BDSKSearchBookmarkController sharedBookmarkController] 
addBookmarkWithInfo:[group dictionaryValue] label:[searchBookmarkField 
stringValue]];
+        [[BDSKSearchBookmarkController sharedBookmarkController] 
addBookmarkWithInfo:[group dictionaryValue] label:[searchBookmarkField 
stringValue] toFolder:nil];
     }
 }
 

Modified: trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj
===================================================================
--- trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj     2007-11-09 06:45:36 UTC 
(rev 11497)
+++ trunk/bibdesk/Bibdesk.xcodeproj/project.pbxproj     2007-11-09 14:11:25 UTC 
(rev 11498)
@@ -159,6 +159,10 @@
                CE2837420917D31D006B4C63 /* BDSKEdgeView.m in Sources */ = {isa 
= PBXBuildFile; fileRef = CE2837400917D31D006B4C63 /* BDSKEdgeView.m */; };
                CE2941050A7F8F2900A46D05 /* ReadMe.rtf in Resources */ = {isa = 
PBXBuildFile; fileRef = CE2941040A7F8F2900A46D05 /* ReadMe.rtf */; };
                CE2944010A7F939A00A46D05 /* PreferenceSearchTerms.plist in 
Resources */ = {isa = PBXBuildFile; fileRef = CE2944000A7F939A00A46D05 /* 
PreferenceSearchTerms.plist */; };
+               CE2A195F0CE4969900A0499B /* NewFolder.tiff in Resources */ = 
{isa = PBXBuildFile; fileRef = CE2A195D0CE4969800A0499B /* NewFolder.tiff */; };
+               CE2A19600CE4969900A0499B /* NewSeparator.tiff in Resources */ = 
{isa = PBXBuildFile; fileRef = CE2A195E0CE4969800A0499B /* NewSeparator.tiff 
*/; };
+               CE2A198E0CE499AD00A0499B /* SmallFolder.tiff in Resources */ = 
{isa = PBXBuildFile; fileRef = CE2A198C0CE499AD00A0499B /* SmallFolder.tiff */; 
};
+               CE2A198F0CE499AD00A0499B /* SmallMenu.tiff in Resources */ = 
{isa = PBXBuildFile; fileRef = CE2A198D0CE499AD00A0499B /* SmallMenu.tiff */; };
                CE2AFE5A0911425F00E65C87 /* BDSKGroupCell.m in Sources */ = 
{isa = PBXBuildFile; fileRef = CE2AFE580911425F00E65C87 /* BDSKGroupCell.m */; 
};
                CE2C16F90A0A149E006F0A73 /* gear2.tiff in Resources */ = {isa = 
PBXBuildFile; fileRef = CE2C16F80A0A149E006F0A73 /* gear2.tiff */; };
                CE2C18920A0A43BE006F0A73 /* importFolderIcon.tiff in Resources 
*/ = {isa = PBXBuildFile; fileRef = CE2C18910A0A43BE006F0A73 /* 
importFolderIcon.tiff */; };
@@ -987,6 +991,10 @@
                CE28346209176C88006B4C63 /* NSBezierPath_CoreImageExtensions.m 
*/ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = 
sourcecode.c.objc; path = NSBezierPath_CoreImageExtensions.m; sourceTree = 
"<group>"; };
                CE28373F0917D31D006B4C63 /* BDSKEdgeView.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
BDSKEdgeView.h; sourceTree = "<group>"; };
                CE2837400917D31D006B4C63 /* BDSKEdgeView.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= BDSKEdgeView.m; sourceTree = "<group>"; };
+               CE2A195D0CE4969800A0499B /* NewFolder.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = NewFolder.tiff; path = 
Images/NewFolder.tiff; sourceTree = "<group>"; };
+               CE2A195E0CE4969800A0499B /* NewSeparator.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = NewSeparator.tiff; 
path = Images/NewSeparator.tiff; sourceTree = "<group>"; };
+               CE2A198C0CE499AD00A0499B /* SmallFolder.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = SmallFolder.tiff; path 
= Images/SmallFolder.tiff; sourceTree = "<group>"; };
+               CE2A198D0CE499AD00A0499B /* SmallMenu.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = SmallMenu.tiff; path = 
Images/SmallMenu.tiff; sourceTree = "<group>"; };
                CE2AFE570911425F00E65C87 /* BDSKGroupCell.h */ = {isa = 
PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = 
BDSKGroupCell.h; sourceTree = "<group>"; };
                CE2AFE580911425F00E65C87 /* BDSKGroupCell.m */ = {isa = 
PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; 
path = BDSKGroupCell.m; sourceTree = "<group>"; };
                CE2C16F80A0A149E006F0A73 /* gear2.tiff */ = {isa = 
PBXFileReference; lastKnownFileType = image.tiff; name = gear2.tiff; path = 
Images/gear2.tiff; sourceTree = "<group>"; };
@@ -2262,6 +2270,10 @@
                F9022DDA0758089500C3F701 /* Images */ = {
                        isa = PBXGroup;
                        children = (
+                               CE2A198C0CE499AD00A0499B /* SmallFolder.tiff */,
+                               CE2A198D0CE499AD00A0499B /* SmallMenu.tiff */,
+                               CE2A195D0CE4969800A0499B /* NewFolder.tiff */,
+                               CE2A195E0CE4969800A0499B /* NewSeparator.tiff 
*/,
                                CE7E207C0A0BF833009D04C3 /* 
GroupAddSmart_Pressed.tiff */,
                                CE7E207D0A0BF833009D04C3 /* GroupAddSmart.tiff 
*/,
                                F9022DA20758088000C3F701 /* Action_Pressed.tiff 
*/,
@@ -2874,7 +2886,6 @@
                29B97313FDCFA39411CA2CEA /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = F993F20208553A61007A7657 /* 
Build configuration list for PBXProject "Bibdesk" */;
-                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 29B97314FDCFA39411CA2CEA /* BibDesk */;
                        projectDirPath = "";
@@ -3257,6 +3268,10 @@
                                CE8962C60CBEC0C500EA2D98 /* 
TemplateOptions.strings in Resources */,
                                CE8962CB0CBEC10700EA2D98 /* 
TemplateOptions.plist in Resources */,
                                CE023F5D0CC50F87003F52E5 /* Add_Small.tiff in 
Resources */,
+                               CE2A195F0CE4969900A0499B /* NewFolder.tiff in 
Resources */,
+                               CE2A19600CE4969900A0499B /* NewSeparator.tiff 
in Resources */,
+                               CE2A198E0CE499AD00A0499B /* SmallFolder.tiff in 
Resources */,
+                               CE2A198F0CE499AD00A0499B /* SmallMenu.tiff in 
Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };

Modified: trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/classes.nib
===================================================================
--- trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/classes.nib   
2007-11-09 06:45:36 UTC (rev 11497)
+++ trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/classes.nib   
2007-11-09 14:11:25 UTC (rev 11498)
@@ -1,11 +1,28 @@
 {
     IBClasses = (
         {
+            CLASS = BDSKBookmarkOutlineView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSOutlineView; 
+        }, 
+        {
+            CLASS = BDSKFilePathCell; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = BDSKTextWithIconCell; 
+        }, 
+        {CLASS = BDSKSearchBookmark; LANGUAGE = ObjC; SUPERCLASS = NSObject; 
}, 
+        {
+            ACTIONS = {
+                deleteBookmark = id; 
+                insertBookmarkFolder = id; 
+                insertBookmarkSeparator = id; 
+            }; 
             CLASS = BDSKSearchBookmarkController; 
             LANGUAGE = ObjC; 
-            OUTLETS = {tableView = NSTableView; }; 
+            OUTLETS = {outlineView = NSOutlineView; }; 
             SUPERCLASS = NSWindowController; 
         }, 
+        {CLASS = BDSKTextWithIconCell; LANGUAGE = ObjC; SUPERCLASS = 
NSTextFieldCell; }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
     ); 
     IBVersion = 1; 

Modified: trunk/bibdesk/English.lproj/SearchBookmarksWindow.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/classes.nib
===================================================================
--- trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/classes.nib    
2007-11-09 06:45:36 UTC (rev 11497)
+++ trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/classes.nib    
2007-11-09 14:11:25 UTC (rev 11498)
@@ -1,12 +1,28 @@
 {
     IBClasses = (
+        {
+            CLASS = BDSKBookmarkOutlineView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSOutlineView; 
+        }, 
+        {
+            CLASS = BDSKFilePathCell; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = BDSKTextWithIconCell; 
+        }, 
         {CLASS = BDSKSearchBookmark; LANGUAGE = ObjC; SUPERCLASS = NSObject; 
}, 
         {
+            ACTIONS = {
+                deleteBookmark = id; 
+                insertBookmarkFolder = id; 
+                insertBookmarkSeparator = id; 
+            }; 
             CLASS = BDSKSearchBookmarkController; 
             LANGUAGE = ObjC; 
-            OUTLETS = {tableView = NSTableView; }; 
+            OUTLETS = {outlineView = NSOutlineView; }; 
             SUPERCLASS = NSWindowController; 
         }, 
+        {CLASS = BDSKTextWithIconCell; LANGUAGE = ObjC; SUPERCLASS = 
NSTextFieldCell; }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
     ); 
     IBVersion = 1; 

Modified: trunk/bibdesk/French.lproj/SearchBookmarksWindow.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Added: trunk/bibdesk/Images/NewFolder.tiff
===================================================================
(Binary files differ)


Property changes on: trunk/bibdesk/Images/NewFolder.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/bibdesk/Images/NewSeparator.tiff
===================================================================
(Binary files differ)


Property changes on: trunk/bibdesk/Images/NewSeparator.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/bibdesk/Images/SmallFolder.tiff
===================================================================
(Binary files differ)


Property changes on: trunk/bibdesk/Images/SmallFolder.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/bibdesk/Images/SmallMenu.tiff
===================================================================
(Binary files differ)


Property changes on: trunk/bibdesk/Images/SmallMenu.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to