Annotation of chimera/BookmarksService.mm, revision 1.3

1.1       hyatt       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: 
1.2       hyatt      54: -(IBAction)addBookmark:(id)aSender
                     55: {
                     56:     if (!mBookmarks)
                     57:         return;
                     58:         
                     59:     nsCOMPtr<nsIContent> content;
                     60:     int index = [mOutlineView selectedRow];
                     61:     
                     62:     if (index > 0) {
                     63:         BookmarkItem* item = [mOutlineView itemAtRow: index];
                     64:         if (![mOutlineView isExpandable: item])
                     65:             content = [item contentNode];
                     66:     }
                     67:     
                     68:     if (!content)
                     69:         mBookmarks->GetRootContent(getter_AddRefs(content));
                     70:         
                     71:     nsCOMPtr<nsIDocument> doc;
                     72:     content->GetDocument(*getter_AddRefs(doc));
                     73:     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
                     74:     nsCOMPtr<nsIDOMElement> elt;
                     75:     domDoc->CreateElementNS(NS_LITERAL_STRING("http://chimera.mozdev.org/bookmarks"), 
                     76:                             NS_LITERAL_STRING("bookmark"), 
                     77:                             getter_AddRefs(elt));
                     78:     
                     79:     elt->SetAttribute(NS_LITERAL_STRING("title"), NS_LITERAL_STRING("MozillaZine"));
                     80:     elt->SetAttribute(NS_LITERAL_STRING("href"), NS_LITERAL_STRING("http://www.mozillazine.org/"));
                     81:     
                     82:     nsCOMPtr<nsIDOMElement> parent(do_QueryInterface(content));
                     83:     nsCOMPtr<nsIDOMNode> dummy;
                     84:     parent->AppendChild(elt, getter_AddRefs(dummy));
                     85: }
                     86: 
                     87: -(IBAction)deleteBookmark: (id)aSender
                     88: {
                     89: }
                     90: 
1.1       hyatt      91: -(IBAction)openBookmark: (id)aSender
                     92: {
                     93:     int index = [mOutlineView selectedRow];
                     94:     if (index == -1)
                     95:         return;
                     96:     
                     97:     id item = [mOutlineView itemAtRow: index];
                     98:     if (!item)
                     99:         return;
                    100:         
                    101:     if ([mOutlineView isExpandable: item]) {
                    102:         if ([mOutlineView isItemExpanded: item])
                    103:             [mOutlineView collapseItem: item];
                    104:         else
                    105:             [mOutlineView expandItem: item];
                    106:     }
                    107:     else {
                    108:         nsIContent* content = [item contentNode];
                    109:         nsAutoString href;
                    110:         content->GetAttr(kNameSpaceID_None, BookmarksService::gHrefAtom, href);
                    111:         if (!href.IsEmpty()) {
                    112:             nsCAutoString cstr; cstr.AssignWithConversion(href);
                    113:             NSString* url = [NSString stringWithCString: cstr.get()];
                    114:             [[mBrowserView getBrowserView] loadURI:[NSURL URLWithString: url] flags:NSLoadFlagsNone];
                    115:         }
                    116:     } 
                    117: }
                    118: 
                    119: - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
                    120: {
                    121:     if (!mBookmarks)
                    122:         return nil;
                    123:        
                    124:     nsCOMPtr<nsIContent> content;
                    125:     if (!item)
                    126:         mBookmarks->GetRootContent(getter_AddRefs(content));
                    127:     else
                    128:         content = [item contentNode];
                    129:     
                    130:     nsCOMPtr<nsIContent> child;
                    131:     content->ChildAt(index, *getter_AddRefs(child));
                    132:     return mBookmarks->GetWrapperFor(child);
                    133: }
                    134: 
                    135: - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
                    136: {
                    137:     if (!mBookmarks)
                    138:         return NO;
                    139:     
                    140:     if (!item)
                    141:         return YES; // The root node is always open.
                    142:     
                    143:     nsCOMPtr<nsIAtom> tagName;
                    144:     nsIContent* content = [item contentNode];
                    145:     content->GetTag(*getter_AddRefs(tagName));
                    146:     
                    147:     return (tagName == BookmarksService::gFolderAtom);
                    148: }
                    149: 
                    150: - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
                    151: {
                    152:     if (!mBookmarks)
                    153:         return 0;
1.2       hyatt     154:   
1.1       hyatt     155:     nsCOMPtr<nsIContent> content;
                    156:     if (!item)
                    157:         mBookmarks->GetRootContent(getter_AddRefs(content));
                    158:     else 
                    159:         content = [item contentNode];
                    160:     
                    161:     PRInt32 childCount;
                    162:     content->ChildCount(childCount);
                    163:     
                    164:     return childCount;
                    165: }
                    166: 
                    167: - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
                    168: {
                    169:     if (!item)
                    170:         return nil;
                    171:     
                    172:     NSString* columnName = [tableColumn identifier];
                    173:       
                    174:     if ([columnName isEqualToString: @"name"]) {
                    175:         nsIContent* content = [item contentNode];
                    176:         nsAutoString nameAttr;
                    177:         content->GetAttr(kNameSpaceID_None, BookmarksService::gNameAtom, nameAttr);
                    178:         nsCAutoString cStr; cStr.AssignWithConversion(nameAttr);
                    179:         return [NSString stringWithCString: cStr.get()];
                    180:     }
                    181:     
                    182:     return nil;
                    183: }
                    184: 
                    185: - (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
                    186: {
                    187: }
                    188: 
                    189: @end
                    190: 
                    191: @implementation BookmarkItem
                    192: -(nsIContent*)contentNode
                    193: {
                    194:     return mContentNode;
                    195: }
                    196: 
                    197: -(void)setContentNode: (nsIContent*)aContentNode
                    198: {
                    199:     mContentNode = aContentNode;
                    200: }
                    201: @end
                    202: 
                    203: // Helper for stripping whitespace
                    204: static void
                    205: StripWhitespaceNodes(nsIContent* aElement)
                    206: {
                    207:     PRInt32 childCount;
                    208:     aElement->ChildCount(childCount);
                    209:     for (PRInt32 i = 0; i < childCount; i++) {
                    210:         nsCOMPtr<nsIContent> child;
                    211:         aElement->ChildAt(i, *getter_AddRefs(child));
                    212:         nsCOMPtr<nsITextContent> text = do_QueryInterface(child);
                    213:         if (text) {
                    214:             PRBool isEmpty;
                    215:             text->IsOnlyWhitespace(&isEmpty);
                    216:             if (isEmpty) {
                    217:                 // This node contained nothing but whitespace.
                    218:                 // Remove it from the content model.
                    219:                 aElement->RemoveChildAt(i, PR_TRUE);
                    220:                 i--; // Decrement our count, since we just removed this child.
                    221:                 childCount--; // Also decrement our total count.
                    222:             }
                    223:         }
                    224:         else StripWhitespaceNodes(child);
                    225:     }
                    226: }
                    227: 
                    228: PRUint32 BookmarksService::gRefCnt = 0;
                    229: BookmarksService* BookmarksService::gSingleton = nsnull;
                    230: nsIAtom* BookmarksService::gFolderAtom = nsnull;
                    231: nsIAtom* BookmarksService::gBookmarkAtom = nsnull;
                    232: nsIAtom* BookmarksService::gHrefAtom = nsnull;
                    233: nsIAtom* BookmarksService::gNameAtom = nsnull;
                    234: 
                    235: BookmarksService::BookmarksService()
                    236: {
                    237:     mDictionary = nil;
                    238:     nsCOMPtr<nsIFile> profileDir;
                    239:     NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(profileDir));
                    240:     profileDir->Append("bookmarks.xml");
                    241: 
                    242:     nsXPIDLCString bookmarksFileURL;
                    243:     NS_GetURLSpecFromFile(profileDir, getter_Copies(bookmarksFileURL));
                    244:     
                    245:     nsCOMPtr<nsIURI> uri;
                    246:     NS_NewURI(getter_AddRefs(uri), bookmarksFileURL.get());
1.3     ! hyatt     247: 
        !           248:     nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));    
1.1       hyatt     249:     xblService->FetchSyncXMLDocument(uri, getter_AddRefs(mBookmarks));
                    250:     
                    251:     nsCOMPtr<nsIContent> rootNode;
                    252:     GetRootContent(getter_AddRefs(rootNode));
                    253:     StripWhitespaceNodes(rootNode);
                    254: }
                    255: 
                    256: BookmarksService::~BookmarksService()
                    257: {
                    258:     [mDictionary release];
                    259: }
                    260: 
                    261: void
                    262: BookmarksService::GetRootContent(nsIContent** aResult)
                    263: {
                    264:     *aResult = nsnull;
                    265:     if (mBookmarks) {
                    266:         nsCOMPtr<nsIDOMElement> elt;
                    267:         nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mBookmarks));
                    268:         domDoc->GetDocumentElement(getter_AddRefs(elt));
                    269:         elt->QueryInterface(NS_GET_IID(nsIContent), (void**)aResult); // Addref happens here.
                    270:     }
                    271: }
                    272: 
                    273: BookmarkItem*
                    274: BookmarksService::GetWrapperFor(nsIContent* aContent)
                    275: {
                    276:     if (!mDictionary)
                    277:         mDictionary = [[NSMutableDictionary alloc] initWithCapacity: 30];
                    278:     
                    279:     PRUint32 contentID;
                    280:     aContent->GetContentID(&contentID);
                    281:     
                    282:     BookmarkItem* item = [mDictionary objectForKey: [NSNumber numberWithInt: contentID]];
                    283:     if (item)
                    284:         return item;
                    285:     else {
                    286:         // Create an item.
                    287:         item = [[[BookmarkItem alloc] init] autorelease]; // The dictionary retains us.
                    288:         [item setContentNode: aContent];
                    289:         [mDictionary setObject: item forKey: [NSNumber numberWithInt: contentID]];
                    290:     }
                    291:     return item;
                    292: }
                    293: 
                    294: BookmarksService*
                    295: BookmarksService::AddObserver(nsIDocumentObserver* aObserver)
                    296: {
                    297:     gRefCnt++;
                    298:     if (gRefCnt == 1) {
                    299:         gSingleton = new BookmarksService();
                    300:         gBookmarkAtom = NS_NewAtom("bookmark");
                    301:         gFolderAtom = NS_NewAtom("folder");
                    302:         gNameAtom = NS_NewAtom("name");
                    303:         gHrefAtom = NS_NewAtom("href");
                    304:     }
                    305:     
                    306:     return gSingleton;
                    307: }
                    308: 
                    309: void
                    310: BookmarksService::RemoveObserver(nsIDocumentObserver* aObserver)
                    311: {
                    312:     if (gRefCnt == 0)
                    313:         return;
                    314:         
                    315:     gRefCnt--;
                    316:     if (gRefCnt == 0) {
                    317:         delete gSingleton;
                    318:         NS_RELEASE(gBookmarkAtom);
                    319:         NS_RELEASE(gFolderAtom);
                    320:         NS_RELEASE(gNameAtom);
                    321:         NS_RELEASE(gHrefAtom);
                    322:     }
                    323: }
                    324: 

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