Camino only: Bug 322093 - Bookmark Import rewrite with progress window and performance improvements (performs majority of import in background thread). Patch by David Haas r=hwaara sr=pink

This commit is contained in:
stridey%gmail.com 2006-09-11 20:14:54 +00:00
Родитель da9955a079
Коммит b8e7d3a0d3
4 изменённых файлов: 176 добавлений и 91 удалений

Просмотреть файл

@ -43,6 +43,9 @@
IBOutlet NSPopUpButton* mBrowserListButton;
IBOutlet NSButton* mCancelButton;
IBOutlet NSButton* mImportButton;
IBOutlet NSProgressIndicator* mImportProgressBar;
IBOutlet NSView* mImportView;
IBOutlet NSView* mProgressView;
}
-(void) buildAvailableFileList;
@ -51,5 +54,6 @@
-(IBAction) loadOpenPanel:(id)aSender;
-(IBAction) nullAction:(id)aSender;
-(void) alertSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
-(void) finishThreadedImport:(BOOL)success fromFile:(NSString *)aFile;
@end

Просмотреть файл

@ -47,11 +47,14 @@
-(void) tryAddImportFromBrowser: (NSString *) aBrowserName withBookmarkPath: (NSString *) aPath;
-(void) tryOmniWeb5Import;
-(void) buildButtonForBrowser:(NSString *) aBrowserName withObject:(id)anObject;
-(void) buildButtonForBrowser:(NSString *) aBrowserName withPathArray:(NSArray *)anArray;
-(NSString *) getSaltedBookmarkPathForProfile: (NSString *) aPath;
-(void) beginImportFrom:(NSString *) aPath intoFolder:(BookmarkFolder *) aFolder;
-(void) beginOmniWeb5ImportFrom:(NSArray *)anArray intoFolder:(BookmarkFolder *)aFolder;
-(void) finishImport:(BOOL)success fromFile:(NSString *)aFile intoFolder:(BookmarkFolder*)aFolder;
-(void) beginImportFrom:(NSArray *)aPath withTitles:(NSArray *)anArray;
-(void) beginOmniWeb5ImportFrom:(NSArray *)anArray;
-(void) finishImport:(BOOL)success fromFiles:(NSArray *)anArray;
-(void) finishThreadedImport:(BOOL)success fromFiles:(NSArray *)anArray;
-(void) showProgressView;
-(void) showImportView;
@end
@ -61,8 +64,8 @@
-(void) windowDidLoad
{
[self showImportView];
[self buildAvailableFileList];
[[self window] center];
}
// Check for common webbrower bookmark files and, if they exist, add import buttons.
@ -107,7 +110,7 @@
NSFileManager *fm = [NSFileManager defaultManager];
NSString *fullPathString = [aPath stringByStandardizingPath];
if ([fm fileExistsAtPath:fullPathString]) {
[self buildButtonForBrowser:aBrowserName withObject:fullPathString];
[self buildButtonForBrowser:aBrowserName withPathArray:[NSArray arrayWithObject:fullPathString]];
}
}
@ -131,7 +134,7 @@
}
if ([haveFiles count] > 0)
{
[self buildButtonForBrowser:@"OmniWeb 5" withObject:haveFiles];
[self buildButtonForBrowser:@"OmniWeb 5" withPathArray:haveFiles];
}
}
@ -153,13 +156,13 @@
return nil;
}
-(void) buildButtonForBrowser:(NSString *) aBrowserName withObject:(id)aThingy
-(void) buildButtonForBrowser:(NSString *) aBrowserName withPathArray:(NSArray *)anArray
{
[mBrowserListButton insertItemWithTitle:aBrowserName atIndex:0];
NSMenuItem *browserItem = [mBrowserListButton itemAtIndex:0];
[browserItem setTarget:self];
[browserItem setAction:@selector(nullAction:)];
[browserItem setRepresentedObject:aThingy];
[browserItem setRepresentedObject:anArray];
}
// keeps browsers turned on
@ -175,22 +178,18 @@
-(IBAction) import:(id)aSender
{
// XXX show a spinner, disable the button, postpone to next event loop (to give UI time to update)
NSMenuItem *selectedItem = [mBrowserListButton selectedItem];
BookmarkFolder *importFolder = [[[BookmarkManager sharedBookmarkManager] rootBookmarks] addBookmarkFolder];
NSString *titleString;
if ([[selectedItem title] isEqualToString:@"Internet Explorer"])
titleString = [[NSString alloc] initWithString:NSLocalizedString(@"Imported IE Favorites", @"")];
titleString = [NSString stringWithString:NSLocalizedString(@"Imported IE Favorites", @"")];
else
titleString = [[NSString alloc] initWithFormat:NSLocalizedString(@"Imported %@ Bookmarks", @""), [selectedItem title]];
[importFolder setTitle:titleString];
[titleString release];
titleString = [NSString stringWithFormat:NSLocalizedString(@"Imported %@ Bookmarks", @""), [selectedItem title]];
// Stupid OmniWeb 5 gets its own import function
if ( [[selectedItem title] isEqualToString:@"OmniWeb 5"] ) {
[self beginOmniWeb5ImportFrom:[selectedItem representedObject] intoFolder:importFolder];
[self beginOmniWeb5ImportFrom:[selectedItem representedObject]];
}
else {
[self beginImportFrom:[selectedItem representedObject] intoFolder:importFolder];
[self beginImportFrom:[selectedItem representedObject] withTitles:[NSArray arrayWithObject:titleString]];
}
}
@ -207,75 +206,56 @@
types: array];
if (result == NSOKButton) {
NSString *pathToFile = [[openPanel filenames] objectAtIndex:0];
BookmarkFolder *importFolder = [[[BookmarkManager sharedBookmarkManager] rootBookmarks] addBookmarkFolder];
[importFolder setTitle:NSLocalizedString(@"Imported Bookmarks",@"Imported Bookmarks")];
[self beginImportFrom:pathToFile intoFolder:importFolder];
[self beginImportFrom:[NSArray arrayWithObject:pathToFile]
withTitles:[NSArray arrayWithObject:NSLocalizedString(@"Imported Bookmarks",@"Imported Bookmarks")]];
}
}
-(void) beginOmniWeb5ImportFrom:(NSArray *)anArray intoFolder:(BookmarkFolder *) aFolder
-(void) beginOmniWeb5ImportFrom:(NSArray *)anArray
{
[mCancelButton setEnabled:NO];
[mImportButton setEnabled:NO];
NSEnumerator *enumerator = [anArray objectEnumerator];
NSMutableArray *titleArray= [NSMutableArray array];
NSString* curFilename = nil;
BOOL success = TRUE;
NSString *curPath;
while ( success && (curPath = [enumerator nextObject] ) )
NSString *curPath = nil;
while ( curPath = [enumerator nextObject] )
{
curFilename = [curPath lastPathComponent];
// What folder we import into depends on what OmniWeb file we're importing.
if ([curFilename isEqualToString:@"Bookmarks.html"] )
{
success = [[BookmarkManager sharedBookmarkManager] importBookmarks:curPath intoFolder:aFolder];
[titleArray addObject:NSLocalizedString(@"Imported OmniWeb 5 Bookmarks", @"Imported OmniWeb 5 Bookmarks")];
}
else if ([curFilename isEqualToString:@"Favorites.html"] )
{
BookmarkFolder *favoriteFolder = [aFolder addBookmarkFolder];
[favoriteFolder setTitle:NSLocalizedString(@"OmniWeb Favorites", @"OmniWeb Favorites")];
success = [[BookmarkManager sharedBookmarkManager] importBookmarks:curPath intoFolder:favoriteFolder];
[titleArray addObject:NSLocalizedString(@"OmniWeb Favorites", @"OmniWeb Favorites")];
}
else if ([curFilename isEqualToString:@"Published.html"])
{
BookmarkFolder *publishedFolder = [aFolder addBookmarkFolder];
[publishedFolder setTitle:NSLocalizedString(@"OmniWeb Published", @"OmniWeb Published")];
success = [[BookmarkManager sharedBookmarkManager] importBookmarks:curPath intoFolder:publishedFolder];
[titleArray addObject:NSLocalizedString(@"OmniWeb Published", @"OmniWeb Published")];
}
}
[mCancelButton setEnabled:YES];
[mImportButton setEnabled:YES];
// Non-rigorous reporting of errors
[self finishImport:success fromFile:curFilename intoFolder:aFolder];
[self beginImportFrom:anArray withTitles:titleArray];
}
-(void) beginImportFrom:(NSString *) aPath intoFolder:(BookmarkFolder *) aFolder
-(void) beginImportFrom:(NSArray *) aPathArray withTitles:(NSArray *)aTitleArray
{
[mCancelButton setEnabled:NO];
[mImportButton setEnabled:NO];
BOOL success = [[BookmarkManager sharedBookmarkManager] importBookmarks:aPath intoFolder:aFolder];
[mCancelButton setEnabled:YES];
[mImportButton setEnabled:YES];
[self finishImport:success fromFile:[aPath lastPathComponent] intoFolder:aFolder];
[self showProgressView];
NSDictionary *aDict = [NSDictionary dictionaryWithObjectsAndKeys: aPathArray, kBookmarkImportPathIndentifier,
aTitleArray, kBookmarkImportNewFolderNameIdentifier, nil];
[NSThread detachNewThreadSelector:@selector(importBookmarksThreadEntry:)
toTarget:[BookmarkManager sharedBookmarkManager]
withObject:aDict];
}
-(void) finishImport:(BOOL)success fromFile:(NSString *)aFile intoFolder:(BookmarkFolder*)aFolder
-(void) finishThreadedImport:(BOOL)success fromFile:(NSString *)aFile
{
//show them the imported bookmarks if import succeeded
if (success)
{
[[self window] orderOut:self];
BrowserWindowController* windowController = [(MainController *)[NSApp delegate] openBrowserWindowWithURL:@"about:bookmarks" andReferrer:nil behind:nil allowPopups:NO];
BookmarkViewController* bmController = [windowController bookmarkViewController];
[bmController setItemToRevealOnLoad:aFolder];
BookmarkFolder *rootFolder = [[BookmarkManager sharedBookmarkManager] rootBookmarks];
BookmarkFolder *newFolder = [rootFolder objectAtIndex:([rootFolder count] - 1)];
[bmController setItemToRevealOnLoad:newFolder];
}
else
{
@ -291,6 +271,8 @@
[NSString stringWithFormat:NSLocalizedString(@"ImportFailureMessage", @"The file '%@' is not a supported bookmark file type."), aFile]
);
}
[[self window] orderOut:self];
[self showImportView];
}
-(void) alertSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
@ -298,4 +280,23 @@
[[self window] orderOut:self];
}
-(void) showProgressView
{
NSSize viewSize = [mProgressView frame].size;
[[self window] setContentView:mProgressView];
[[self window] setContentSize:viewSize];
[[self window] center];
[mImportProgressBar setUsesThreadedAnimation:YES];
[mImportProgressBar startAnimation:self];
}
-(void) showImportView
{
[mImportProgressBar stopAnimation:self];
NSSize viewSize = [mImportView frame].size;
[[self window] setContentView:mImportView];
[[self window] setContentSize:viewSize];
[[self window] center];
}
@end

Просмотреть файл

@ -47,10 +47,12 @@
@class KindaSmartFolderManager;
extern NSString* const kBookmarkManagerStartedNotification;
extern NSString* const kBookmarksToolbarFolderIdentifier;
extern NSString* const kBookmarksMenuFolderIdentifier;
extern NSString* const kBookmarkImportPathIndentifier;
extern NSString* const kBookmarkImportNewFolderNameIdentifier;
const int kBookmarksContextMenuArrangeSeparatorTag = 100;
@ -142,7 +144,7 @@ const int kBookmarksContextMenuArrangeSeparatorTag = 100;
// Importing bookmarks
- (void)startImportBookmarks;
- (BOOL)importBookmarks:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder;
- (void)importBookmarksThreadEntry:(NSDictionary *)aDict;
// Writing bookmark files
- (void)writeHTMLFile:(NSString *)pathToFile;

Просмотреть файл

@ -67,13 +67,20 @@
NSString* const kBookmarkManagerStartedNotification = @"BookmarkManagerStartedNotification";
// root bookmark folder identifiers (must be unique!)
NSString* const kBookmarksToolbarFolderIdentifier = @"BookmarksToolbarFolder";
NSString* const kBookmarksMenuFolderIdentifier = @"BookmarksMenuFolder";
NSString* const kBookmarksToolbarFolderIdentifier = @"BookmarksToolbarFolder";
NSString* const kBookmarksMenuFolderIdentifier = @"BookmarksMenuFolder";
static NSString* const kTop10BookmarksFolderIdentifier = @"Top10BookmarksFolder";
static NSString* const kRendezvousFolderIdentifier = @"RendezvousFolder"; // aka Bonjour
static NSString* const kAddressBookFolderIdentifier = @"AddressBookFolder";
static NSString* const kHistoryFolderIdentifier = @"HistoryFolder";
static NSString* const kTop10BookmarksFolderIdentifier = @"Top10BookmarksFolder";
static NSString* const kRendezvousFolderIdentifier = @"RendezvousFolder"; // aka Bonjour
static NSString* const kAddressBookFolderIdentifier = @"AddressBookFolder";
static NSString* const kHistoryFolderIdentifier = @"HistoryFolder";
NSString* const kBookmarkImportPathIndentifier = @"path";
NSString* const kBookmarkImportNewFolderNameIdentifier = @"title";
static NSString* const kBookmarkImportStatusIndentifier = @"flag";
static NSString* const kBookmarkImportNewFolderIdentifier = @"folder";
static NSString* const kBookmarkImportNewFolderIndexIdentifier = @"index";
// these are suggested indices; we only use them to order the root folders, not to access them.
enum {
@ -111,6 +118,7 @@ enum {
- (BOOL)importHTMLFile:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder;
- (BOOL)importCaminoXMLFile:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder settingToolbarFolder:(BOOL)setToolbarFolder;
- (BOOL)importPropertyListFile:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder;
- (void)importBookmarksThreadReturn:(NSDictionary *)aDict;
- (BOOL)readOperaFile:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder;
@ -601,9 +609,14 @@ static BookmarkManager* gBookmarkManager = nil;
return [mRootBookmarks itemWithUUID:uuid];
}
// only the main thread can get the undo manager.
// imports (on a background thread) get nothing, which is ok.
// this keeps things nice and thread safe
-(NSUndoManager *) undoManager
{
return mUndoManager;
if ([NSThread inMainThread])
return mUndoManager;
return nil;
}
- (void)setPathToBookmarkFile:(NSString *)aString
@ -1466,39 +1479,104 @@ static BookmarkManager* gBookmarkManager = nil;
[mImportDlgController showWindow:nil];
}
- (BOOL)importBookmarks:(NSString *)pathToFile intoFolder:(BookmarkFolder *)aFolder
- (void)importBookmarksThreadEntry:(NSDictionary *)aDict
{
// I feel dirty doing it this way. But we'll check file extension
// to figure out how to handle this.
NSUndoManager *undoManager = [self undoManager];
[undoManager beginUndoGrouping];
BOOL success = NO;
NSString *extension =[pathToFile pathExtension];
if ([extension isEqualToString:@""]) // we'll go out on a limb here
success = [self readOperaFile:pathToFile intoFolder:aFolder];
else if ([extension isEqualToString:@"html"] || [extension isEqualToString:@"htm"])
success = [self importHTMLFile:pathToFile intoFolder:aFolder];
else if ([extension isEqualToString:@"xml"])
success = [self importCaminoXMLFile:pathToFile intoFolder:aFolder settingToolbarFolder:NO];
else if ([extension isEqualToString:@"plist"] || !success)
success = [self importPropertyListFile:pathToFile intoFolder:aFolder];
// we don't know the extension, or we failed to load. we'll take another
// crack at it trying everything we know.
if (!success) {
success = [self readOperaFile:pathToFile intoFolder:aFolder];
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
BOOL success = TRUE;
int currentFile = 0;
NSArray *pathArray = [aDict objectForKey:kBookmarkImportPathIndentifier];
NSArray *titleArray = [aDict objectForKey:kBookmarkImportNewFolderNameIdentifier];
NSString *pathToFile;
NSString *aTitle;
BookmarkFolder *topImportFolder = [[BookmarkFolder alloc] init];
BookmarkFolder *importFolder = topImportFolder;
NSEnumerator *pathEnumerator = [pathArray objectEnumerator];
NSEnumerator *titleEnumerator = [titleArray objectEnumerator];
[self startSuppressingChangeNotifications];
while (success && (pathToFile = [pathEnumerator nextObject]) )
{
if (!importFolder)
{
importFolder = [[BookmarkFolder alloc] init];
}
NSString *extension =[pathToFile pathExtension];
if ([extension isEqualToString:@""]) // we'll go out on a limb here
success = [self readOperaFile:pathToFile intoFolder:importFolder];
else if ([extension isEqualToString:@"html"] || [extension isEqualToString:@"htm"])
success = [self importHTMLFile:pathToFile intoFolder:importFolder];
else if ([extension isEqualToString:@"xml"])
success = [self importCaminoXMLFile:pathToFile intoFolder:importFolder settingToolbarFolder:NO];
else if ([extension isEqualToString:@"plist"] || !success)
success = [self importPropertyListFile:pathToFile intoFolder:importFolder];
// we don't know the extension, or we failed to load. we'll take another
// crack at it trying everything we know.
if (!success) {
success = [self importHTMLFile:pathToFile intoFolder:aFolder];
success = [self readOperaFile:pathToFile intoFolder:importFolder];
if (!success) {
success = [self importCaminoXMLFile:pathToFile intoFolder:aFolder settingToolbarFolder:NO];
success = [self importHTMLFile:pathToFile intoFolder:importFolder];
if (!success) {
success = [self importCaminoXMLFile:pathToFile intoFolder:importFolder settingToolbarFolder:NO];
}
}
}
aTitle = [titleEnumerator nextObject];
if (!aTitle)
aTitle = NSLocalizedString(@"Imported Bookmarks",@"Imported Bookmarks");
[importFolder setTitle:aTitle];
if (importFolder != topImportFolder)
{
[topImportFolder appendChild:importFolder];
[importFolder release];
}
importFolder = nil;
currentFile++;
}
[[undoManager prepareWithInvocationTarget:[self rootBookmarks]] deleteChild:aFolder];
[undoManager endUndoGrouping];
[undoManager setActionName:NSLocalizedString(@"Import Bookmarks", @"")];
return success;
[self stopSuppressingChangeNotifications];
NSDictionary *returnDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:success],kBookmarkImportStatusIndentifier,
[NSNumber numberWithInt:currentFile], kBookmarkImportNewFolderIndexIdentifier,
pathArray, kBookmarkImportPathIndentifier,
topImportFolder, kBookmarkImportNewFolderIdentifier,
nil];
[self performSelectorOnMainThread:@selector(importBookmarksThreadReturn:)
withObject:returnDict
waitUntilDone:YES];
// release the top-level import folder we allocated - somebody else retains it by now if still needed.
[topImportFolder release];
[pool release];
}
-(void)importBookmarksThreadReturn:(NSDictionary *)aDict
{
BOOL success = [[aDict objectForKey:kBookmarkImportStatusIndentifier] boolValue];
NSArray *fileArray = [aDict objectForKey:kBookmarkImportPathIndentifier];
int currentIndex = [[aDict objectForKey:kBookmarkImportNewFolderIndexIdentifier] intValue];
BookmarkFolder *rootFolder = [self rootBookmarks];
BookmarkFolder *importFolder = [aDict objectForKey:kBookmarkImportNewFolderIdentifier];
if (success || ((currentIndex - [fileArray count]) > 0) )
{
NSUndoManager *undoManager = [self undoManager];
[rootFolder appendChild:importFolder];
[undoManager setActionName:NSLocalizedString(@"Import Bookmarks", @"")];
}
[mImportDlgController finishThreadedImport:success
fromFile:[[fileArray objectAtIndex:(--currentIndex)] lastPathComponent] ];
}
// spits out text file as NSString with "proper" encoding based on pretty shitty detection
- (NSString *)decodedTextFile:(NSString *)pathToFile
{