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 (17 years, 3 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Bookmarks work! Update your Mozilla tree though or chimera won't build.

    1: /*
    2:  *  BookmarksService.cpp
    3:  *  Chimera
    4:  *
    5:  *  Created by David Hyatt on Thu Feb 07 2002.
    6:  *  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
    7:  *
    8:  */
    9: 
   10: #import "NSBrowserView.h"
   11: #include "BookmarksService.h"
   12: #include "nsIDocument.h"
   13: #include "nsIContent.h"
   14: #include "nsIAtom.h"
   15: #include "nsITextContent.h"
   16: #include "nsIDOMDocument.h"
   17: #include "nsIDOMElement.h"
   18: #include "nsString.h"
   19: #include "nsIFile.h"
   20: #include "nsAppDirectoryServiceDefs.h"
   21: #include "nsIXMLHttpRequest.h"
   22: #include "nsNetUtil.h"
   23: #include "nsINamespaceManager.h"
   24: #include "nsIXBLService.h"
   25: 
   26: @implementation BookmarksDataSource
   27: 
   28: -(id) init
   29: {
   30:     [super init];
   31:     mBookmarks = nsnull;
   32:     return self;
   33: }
   34: 
   35: -(void) dealloc
   36: {
   37:     [super dealloc];
   38:     if (mBookmarks)
   39:         BookmarksService::RemoveObserver(nsnull);
   40: }
   41: 
   42: -(void) ensureBookmarks
   43: {
   44:     if (mBookmarks)
   45:         return;
   46:     
   47:     mBookmarks = BookmarksService::AddObserver(nsnull);
   48:     
   49:     [mOutlineView setTarget: self];
   50:     [mOutlineView setDoubleAction: @selector(openBookmark:)];
   51:     [mOutlineView reloadData];
   52: }
   53: 
   54: -(IBAction)openBookmark: (id)aSender
   55: {
   56:     printf("Opening bookmark!\n");
   57:     
   58:     int index = [mOutlineView selectedRow];
   59:     if (index == -1)
   60:         return;
   61:     
   62:     id item = [mOutlineView itemAtRow: index];
   63:     if (!item)
   64:         return;
   65:         
   66:     if ([mOutlineView isExpandable: item]) {
   67:         if ([mOutlineView isItemExpanded: item])
   68:             [mOutlineView collapseItem: item];
   69:         else
   70:             [mOutlineView expandItem: item];
   71:     }
   72:     else {
   73:         nsIContent* content = [item contentNode];
   74:         nsAutoString href;
   75:         content->GetAttr(kNameSpaceID_None, BookmarksService::gHrefAtom, href);
   76:         if (!href.IsEmpty()) {
   77:             nsCAutoString cstr; cstr.AssignWithConversion(href);
   78:             NSString* url = [NSString stringWithCString: cstr.get()];
   79:             [[mBrowserView getBrowserView] loadURI:[NSURL URLWithString: url] flags:NSLoadFlagsNone];
   80:         }
   81:     } 
   82: }
   83: 
   84: - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
   85: {
   86:     if (!mBookmarks)
   87:         return nil;
   88:        
   89:     printf("Begin item obtain\n");
   90:     nsCOMPtr<nsIContent> content;
   91:     if (!item)
   92:         mBookmarks->GetRootContent(getter_AddRefs(content));
   93:     else
   94:         content = [item contentNode];
   95:     
   96:     nsCOMPtr<nsIContent> child;
   97:     content->ChildAt(index, *getter_AddRefs(child));
   98:     return mBookmarks->GetWrapperFor(child);
   99: }
  100: 
  101: - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
  102: {
  103:     if (!mBookmarks)
  104:         return NO;
  105:     
  106:     if (!item)
  107:         return YES; // The root node is always open.
  108:         
  109:     printf("Begin expandable check.\n");
  110:     
  111:     nsCOMPtr<nsIAtom> tagName;
  112:     nsIContent* content = [item contentNode];
  113:     content->GetTag(*getter_AddRefs(tagName));
  114:     
  115:     return (tagName == BookmarksService::gFolderAtom);
  116: }
  117: 
  118: - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
  119: {
  120:     if (!mBookmarks)
  121:         return 0;
  122:  
  123:     printf("Begin child count.\n");
  124:     
  125:     nsCOMPtr<nsIContent> content;
  126:     if (!item)
  127:         mBookmarks->GetRootContent(getter_AddRefs(content));
  128:     else 
  129:         content = [item contentNode];
  130:     
  131:     if (!content)
  132:         printf("OH NO!!!!!\n");
  133:         
  134:     PRInt32 childCount;
  135:     content->ChildCount(childCount);
  136:     
  137:     printf("Child count is %d\n", childCount);
  138:     
  139:     return childCount;
  140: }
  141: 
  142: - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
  143: {
  144:     if (!item)
  145:         return nil;
  146:     
  147:     printf("Obtaining string.\n");
  148:     
  149:     NSString* columnName = [tableColumn identifier];
  150:     if (columnName)
  151:       printf("It has a name!\n");
  152:       
  153:     if ([columnName isEqualToString: @"name"]) {
  154:         nsIContent* content = [item contentNode];
  155:         nsAutoString nameAttr;
  156:         content->GetAttr(kNameSpaceID_None, BookmarksService::gNameAtom, nameAttr);
  157:         nsCAutoString cStr; cStr.AssignWithConversion(nameAttr);
  158:         printf("Well? %s\n", cStr.get());
  159:         return [NSString stringWithCString: cStr.get()];
  160:     }
  161:     
  162:     return nil;
  163: }
  164: 
  165: - (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
  166: {
  167: }
  168: 
  169: @end
  170: 
  171: @implementation BookmarkItem
  172: -(nsIContent*)contentNode
  173: {
  174:     return mContentNode;
  175: }
  176: 
  177: -(void)setContentNode: (nsIContent*)aContentNode
  178: {
  179:     mContentNode = aContentNode;
  180: }
  181: @end
  182: 
  183: // Helper for stripping whitespace
  184: static void
  185: StripWhitespaceNodes(nsIContent* aElement)
  186: {
  187:     PRInt32 childCount;
  188:     aElement->ChildCount(childCount);
  189:     for (PRInt32 i = 0; i < childCount; i++) {
  190:         nsCOMPtr<nsIContent> child;
  191:         aElement->ChildAt(i, *getter_AddRefs(child));
  192:         nsCOMPtr<nsITextContent> text = do_QueryInterface(child);
  193:         if (text) {
  194:             PRBool isEmpty;
  195:             text->IsOnlyWhitespace(&isEmpty);
  196:             if (isEmpty) {
  197:                 // This node contained nothing but whitespace.
  198:                 // Remove it from the content model.
  199:                 aElement->RemoveChildAt(i, PR_TRUE);
  200:                 i--; // Decrement our count, since we just removed this child.
  201:                 childCount--; // Also decrement our total count.
  202:             }
  203:         }
  204:         else StripWhitespaceNodes(child);
  205:     }
  206: }
  207: 
  208: PRUint32 BookmarksService::gRefCnt = 0;
  209: BookmarksService* BookmarksService::gSingleton = nsnull;
  210: nsIAtom* BookmarksService::gFolderAtom = nsnull;
  211: nsIAtom* BookmarksService::gBookmarkAtom = nsnull;
  212: nsIAtom* BookmarksService::gHrefAtom = nsnull;
  213: nsIAtom* BookmarksService::gNameAtom = nsnull;
  214: 
  215: BookmarksService::BookmarksService()
  216: {
  217:     mDictionary = nil;
  218:     nsCOMPtr<nsIFile> profileDir;
  219:     NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(profileDir));
  220:     profileDir->Append("bookmarks.xml");
  221: 
  222:     nsXPIDLCString bookmarksFileURL;
  223:     NS_GetURLSpecFromFile(profileDir, getter_Copies(bookmarksFileURL));
  224:     
  225:     nsCOMPtr<nsIURI> uri;
  226:     NS_NewURI(getter_AddRefs(uri), bookmarksFileURL.get());
  227:       
  228:     nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
  229:     
  230:     xblService->FetchSyncXMLDocument(uri, getter_AddRefs(mBookmarks));
  231:     
  232:     nsCOMPtr<nsIContent> rootNode;
  233:     GetRootContent(getter_AddRefs(rootNode));
  234:     
  235:     if (!rootNode)
  236:         printf("OH SHIT\n");
  237:         
  238:     StripWhitespaceNodes(rootNode);
  239: }
  240: 
  241: BookmarksService::~BookmarksService()
  242: {
  243:     [mDictionary release];
  244: }
  245: 
  246: void
  247: BookmarksService::GetRootContent(nsIContent** aResult)
  248: {
  249:     *aResult = nsnull;
  250:     if (mBookmarks) {
  251:         nsCOMPtr<nsIDOMElement> elt;
  252:         nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mBookmarks));
  253:         domDoc->GetDocumentElement(getter_AddRefs(elt));
  254:         elt->QueryInterface(NS_GET_IID(nsIContent), (void**)aResult); // Addref happens here.
  255:     }
  256: }
  257: 
  258: BookmarkItem*
  259: BookmarksService::GetWrapperFor(nsIContent* aContent)
  260: {
  261:     if (!mDictionary)
  262:         mDictionary = [[NSMutableDictionary alloc] initWithCapacity: 30];
  263:     
  264:     PRUint32 contentID;
  265:     aContent->GetContentID(&contentID);
  266:     
  267:     BookmarkItem* item = [mDictionary objectForKey: [NSNumber numberWithInt: contentID]];
  268:     if (item)
  269:         return item;
  270:     else {
  271:         // Create an item.
  272:         item = [[[BookmarkItem alloc] init] autorelease]; // The dictionary retains us.
  273:         [item setContentNode: aContent];
  274:         [mDictionary setObject: item forKey: [NSNumber numberWithInt: contentID]];
  275:     }
  276:     return item;
  277: }
  278: 
  279: BookmarksService*
  280: BookmarksService::AddObserver(nsIDocumentObserver* aObserver)
  281: {
  282:     gRefCnt++;
  283:     if (gRefCnt == 1) {
  284:         gSingleton = new BookmarksService();
  285:         gBookmarkAtom = NS_NewAtom("bookmark");
  286:         gFolderAtom = NS_NewAtom("folder");
  287:         gNameAtom = NS_NewAtom("name");
  288:         gHrefAtom = NS_NewAtom("href");
  289:     }
  290:     
  291:     return gSingleton;
  292: }
  293: 
  294: void
  295: BookmarksService::RemoveObserver(nsIDocumentObserver* aObserver)
  296: {
  297:     if (gRefCnt == 0)
  298:         return;
  299:         
  300:     gRefCnt--;
  301:     if (gRefCnt == 0) {
  302:         delete gSingleton;
  303:         NS_RELEASE(gBookmarkAtom);
  304:         NS_RELEASE(gFolderAtom);
  305:         NS_RELEASE(gNameAtom);
  306:         NS_RELEASE(gHrefAtom);
  307:     }
  308: }
  309: 

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