File:  [mozdev] / chimera / BookmarksService.mm
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sat Feb 9 01:24:11 2002 UTC (15 years, 8 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Stubs for adding bookmarks.

/*
 *  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)addBookmark:(id)aSender
{
    if (!mBookmarks)
        return;
        
    nsCOMPtr<nsIContent> content;
    int index = [mOutlineView selectedRow];
    
    if (index > 0) {
        BookmarkItem* item = [mOutlineView itemAtRow: index];
        if (![mOutlineView isExpandable: item])
            content = [item contentNode];
    }
    
    if (!content)
        mBookmarks->GetRootContent(getter_AddRefs(content));
        
    nsCOMPtr<nsIDocument> doc;
    content->GetDocument(*getter_AddRefs(doc));
    nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
    nsCOMPtr<nsIDOMElement> elt;
    domDoc->CreateElementNS(NS_LITERAL_STRING("http://chimera.mozdev.org/bookmarks"), 
                            NS_LITERAL_STRING("bookmark"), 
                            getter_AddRefs(elt));
    
    elt->SetAttribute(NS_LITERAL_STRING("title"), NS_LITERAL_STRING("MozillaZine"));
    elt->SetAttribute(NS_LITERAL_STRING("href"), NS_LITERAL_STRING("http://www.mozillazine.org/"));
    
    nsCOMPtr<nsIDOMElement> parent(do_QueryInterface(content));
    nsCOMPtr<nsIDOMNode> dummy;
    parent->AppendChild(elt, getter_AddRefs(dummy));
}

-(IBAction)deleteBookmark: (id)aSender
{
}

-(IBAction)openBookmark: (id)aSender
{
    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;
       
    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.
    
    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;
  
    nsCOMPtr<nsIContent> content;
    if (!item)
        mBookmarks->GetRootContent(getter_AddRefs(content));
    else 
        content = [item contentNode];
    
    PRInt32 childCount;
    content->ChildCount(childCount);
    
    return childCount;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    if (!item)
        return nil;
    
    NSString* columnName = [tableColumn identifier];
      
    if ([columnName isEqualToString: @"name"]) {
        nsIContent* content = [item contentNode];
        nsAutoString nameAttr;
        content->GetAttr(kNameSpaceID_None, BookmarksService::gNameAtom, nameAttr);
        nsCAutoString cStr; cStr.AssignWithConversion(nameAttr);
        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<nsIXMLHttpRequest> req(do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID));
    req->OpenRequest("GET", bookmarksFileURL.get(), PR_FALSE, nsnull, nsnull);
    req->Send(nsnull);
    nsCOMPtr<nsIDOMDocument> doc;
    req->GetResponseXML(getter_AddRefs(doc));
    if (!doc)
        printf("OH NO!\n");
        
    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>