File:  [mozdev] / chimera / BookmarksService.mm
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Sat Feb 9 00:00:47 2002 UTC (15 years, 10 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Bookmarks work! Update your Mozilla tree though or chimera won't build.

/*
 *  BookmarksService.cpp
 *  Chimera
 *
 *  Created by David Hyatt on Thu Feb 07 2002.
 *  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
 *
 */

#import "NSBrowserView.h"
#include "BookmarksService.h"
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsIAtom.h"
#include "nsITextContent.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsString.h"
#include "nsIFile.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIXMLHttpRequest.h"
#include "nsNetUtil.h"
#include "nsINamespaceManager.h"
#include "nsIXBLService.h"

@implementation BookmarksDataSource

-(id) init
{
    [super init];
    mBookmarks = nsnull;
    return self;
}

-(void) dealloc
{
    [super dealloc];
    if (mBookmarks)
        BookmarksService::RemoveObserver(nsnull);
}

-(void) ensureBookmarks
{
    if (mBookmarks)
        return;
    
    mBookmarks = BookmarksService::AddObserver(nsnull);
    
    [mOutlineView setTarget: self];
    [mOutlineView setDoubleAction: @selector(openBookmark:)];
    [mOutlineView reloadData];
}

-(IBAction)openBookmark: (id)aSender
{
    printf("Opening bookmark!\n");
    
    int index = [mOutlineView selectedRow];
    if (index == -1)
        return;
    
    id item = [mOutlineView itemAtRow: index];
    if (!item)
        return;
        
    if ([mOutlineView isExpandable: item]) {
        if ([mOutlineView isItemExpanded: item])
            [mOutlineView collapseItem: item];
        else
            [mOutlineView expandItem: item];
    }
    else {
        nsIContent* content = [item contentNode];
        nsAutoString href;
        content->GetAttr(kNameSpaceID_None, BookmarksService::gHrefAtom, href);
        if (!href.IsEmpty()) {
            nsCAutoString cstr; cstr.AssignWithConversion(href);
            NSString* url = [NSString stringWithCString: cstr.get()];
            [[mBrowserView getBrowserView] loadURI:[NSURL URLWithString: url] flags:NSLoadFlagsNone];
        }
    } 
}

- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
{
    if (!mBookmarks)
        return nil;
       
    printf("Begin item obtain\n");
    nsCOMPtr<nsIContent> content;
    if (!item)
        mBookmarks->GetRootContent(getter_AddRefs(content));
    else
        content = [item contentNode];
    
    nsCOMPtr<nsIContent> child;
    content->ChildAt(index, *getter_AddRefs(child));
    return mBookmarks->GetWrapperFor(child);
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    if (!mBookmarks)
        return NO;
    
    if (!item)
        return YES; // The root node is always open.
        
    printf("Begin expandable check.\n");
    
    nsCOMPtr<nsIAtom> tagName;
    nsIContent* content = [item contentNode];
    content->GetTag(*getter_AddRefs(tagName));
    
    return (tagName == BookmarksService::gFolderAtom);
}

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    if (!mBookmarks)
        return 0;
 
    printf("Begin child count.\n");
    
    nsCOMPtr<nsIContent> content;
    if (!item)
        mBookmarks->GetRootContent(getter_AddRefs(content));
    else 
        content = [item contentNode];
    
    if (!content)
        printf("OH NO!!!!!\n");
        
    PRInt32 childCount;
    content->ChildCount(childCount);
    
    printf("Child count is %d\n", childCount);
    
    return childCount;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    if (!item)
        return nil;
    
    printf("Obtaining string.\n");
    
    NSString* columnName = [tableColumn identifier];
    if (columnName)
      printf("It has a name!\n");
      
    if ([columnName isEqualToString: @"name"]) {
        nsIContent* content = [item contentNode];
        nsAutoString nameAttr;
        content->GetAttr(kNameSpaceID_None, BookmarksService::gNameAtom, nameAttr);
        nsCAutoString cStr; cStr.AssignWithConversion(nameAttr);
        printf("Well? %s\n", cStr.get());
        return [NSString stringWithCString: cStr.get()];
    }
    
    return nil;
}

- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
}

@end

@implementation BookmarkItem
-(nsIContent*)contentNode
{
    return mContentNode;
}

-(void)setContentNode: (nsIContent*)aContentNode
{
    mContentNode = aContentNode;
}
@end

// Helper for stripping whitespace
static void
StripWhitespaceNodes(nsIContent* aElement)
{
    PRInt32 childCount;
    aElement->ChildCount(childCount);
    for (PRInt32 i = 0; i < childCount; i++) {
        nsCOMPtr<nsIContent> child;
        aElement->ChildAt(i, *getter_AddRefs(child));
        nsCOMPtr<nsITextContent> text = do_QueryInterface(child);
        if (text) {
            PRBool isEmpty;
            text->IsOnlyWhitespace(&isEmpty);
            if (isEmpty) {
                // This node contained nothing but whitespace.
                // Remove it from the content model.
                aElement->RemoveChildAt(i, PR_TRUE);
                i--; // Decrement our count, since we just removed this child.
                childCount--; // Also decrement our total count.
            }
        }
        else StripWhitespaceNodes(child);
    }
}

PRUint32 BookmarksService::gRefCnt = 0;
BookmarksService* BookmarksService::gSingleton = nsnull;
nsIAtom* BookmarksService::gFolderAtom = nsnull;
nsIAtom* BookmarksService::gBookmarkAtom = nsnull;
nsIAtom* BookmarksService::gHrefAtom = nsnull;
nsIAtom* BookmarksService::gNameAtom = nsnull;

BookmarksService::BookmarksService()
{
    mDictionary = nil;
    nsCOMPtr<nsIFile> profileDir;
    NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(profileDir));
    profileDir->Append("bookmarks.xml");

    nsXPIDLCString bookmarksFileURL;
    NS_GetURLSpecFromFile(profileDir, getter_Copies(bookmarksFileURL));
    
    nsCOMPtr<nsIURI> uri;
    NS_NewURI(getter_AddRefs(uri), bookmarksFileURL.get());
      
    nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
    
    xblService->FetchSyncXMLDocument(uri, getter_AddRefs(mBookmarks));
    
    nsCOMPtr<nsIContent> rootNode;
    GetRootContent(getter_AddRefs(rootNode));
    
    if (!rootNode)
        printf("OH SHIT\n");
        
    StripWhitespaceNodes(rootNode);
}

BookmarksService::~BookmarksService()
{
    [mDictionary release];
}

void
BookmarksService::GetRootContent(nsIContent** aResult)
{
    *aResult = nsnull;
    if (mBookmarks) {
        nsCOMPtr<nsIDOMElement> elt;
        nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mBookmarks));
        domDoc->GetDocumentElement(getter_AddRefs(elt));
        elt->QueryInterface(NS_GET_IID(nsIContent), (void**)aResult); // Addref happens here.
    }
}

BookmarkItem*
BookmarksService::GetWrapperFor(nsIContent* aContent)
{
    if (!mDictionary)
        mDictionary = [[NSMutableDictionary alloc] initWithCapacity: 30];
    
    PRUint32 contentID;
    aContent->GetContentID(&contentID);
    
    BookmarkItem* item = [mDictionary objectForKey: [NSNumber numberWithInt: contentID]];
    if (item)
        return item;
    else {
        // Create an item.
        item = [[[BookmarkItem alloc] init] autorelease]; // The dictionary retains us.
        [item setContentNode: aContent];
        [mDictionary setObject: item forKey: [NSNumber numberWithInt: contentID]];
    }
    return item;
}

BookmarksService*
BookmarksService::AddObserver(nsIDocumentObserver* aObserver)
{
    gRefCnt++;
    if (gRefCnt == 1) {
        gSingleton = new BookmarksService();
        gBookmarkAtom = NS_NewAtom("bookmark");
        gFolderAtom = NS_NewAtom("folder");
        gNameAtom = NS_NewAtom("name");
        gHrefAtom = NS_NewAtom("href");
    }
    
    return gSingleton;
}

void
BookmarksService::RemoveObserver(nsIDocumentObserver* aObserver)
{
    if (gRefCnt == 0)
        return;
        
    gRefCnt--;
    if (gRefCnt == 0) {
        delete gSingleton;
        NS_RELEASE(gBookmarkAtom);
        NS_RELEASE(gFolderAtom);
        NS_RELEASE(gNameAtom);
        NS_RELEASE(gHrefAtom);
    }
}


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>