diff --git a/frontends/gnustep/AppDelegate.h b/frontends/gnustep/AppDelegate.h index 672bad6bb..102c12463 100644 --- a/frontends/gnustep/AppDelegate.h +++ b/frontends/gnustep/AppDelegate.h @@ -26,6 +26,7 @@ along with this program. If not, see . @interface AppDelegate: NSResponder { @private +NSMutableArray *recentHistory; id downloadsWindowController; id findPanelController; id historyWindowController; diff --git a/frontends/gnustep/AppDelegate.m b/frontends/gnustep/AppDelegate.m index ca8d1a7da..1b5297f59 100644 --- a/frontends/gnustep/AppDelegate.m +++ b/frontends/gnustep/AppDelegate.m @@ -15,6 +15,8 @@ #import "HistoryWindowController.h" #import "Website.h" +#define MAX_RECENT_HISTORY 6 + /** * Set option defaults for (taken from the cocoa frontend) * @@ -43,26 +45,26 @@ static nserror set_defaults(struct nsoption_s *defaults) } -(void)historyUpdated: (NSNotification*)aNotification { - NSLog(@"history updated..."); - NSArray *history = [Website historicWebsites]; + NSLog(@"history updated... %@", aNotification); + id object = [aNotification object]; NSMenu *historyMenu = [[[NSApp menu] itemWithTag: TAG_SUBMENU_HISTORY] submenu]; - for (NSInteger i = [historyMenu numberOfItems] - 1; i > 0; i--) { - [historyMenu removeItemAtIndex: i]; - } - Website *website; - NSMenuItem *menuItem; - for (NSInteger i = 0; i < [history count] && i < 5; i++) { - website = [history objectAtIndex: i]; - menuItem = [[[NSMenuItem alloc] initWithTitle: [website name] + + if ([object isKindOfClass: [Website class]]) { + [recentHistory insertObject: object atIndex: 0]; + NSMenuItem *menuItem = [[[NSMenuItem alloc] initWithTitle: [object name] action: @selector(open) keyEquivalent: nil] autorelease]; - [menuItem setTarget: website]; - [historyMenu addItem: menuItem]; + [menuItem setTarget: object]; + [historyMenu insertItem: menuItem atIndex: 1]; + if ([recentHistory count] > MAX_RECENT_HISTORY) { + [recentHistory removeLastObject]; + [historyMenu removeItemAtIndex: [historyMenu numberOfItems] - 1]; + } } - [historyMenu update]; } -(void)awakeFromNib { NSLog(@"App awake from nib"); + recentHistory = [[NSMutableArray alloc] init]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(historyUpdated:) name: WebsiteHistoryUpdatedNotificationName @@ -127,7 +129,7 @@ static nserror set_defaults(struct nsoption_s *defaults) struct nsurl *url; nserror error; - error = nsurl_create([[[aWebsite url] absoluteString] cString], &url); + error = nsurl_create([[aWebsite url] cString], &url); if (error == NSERROR_OK) { error = browser_window_create(BW_CREATE_HISTORY, url, NULL, NULL, NULL); nsurl_unref(url); diff --git a/frontends/gnustep/BrowserWindowController.m b/frontends/gnustep/BrowserWindowController.m index d635da3ca..79d8680ba 100644 --- a/frontends/gnustep/BrowserWindowController.m +++ b/frontends/gnustep/BrowserWindowController.m @@ -131,7 +131,7 @@ NSString *name = [NSString stringWithCString: title]; NSString *urlStr = [NSString stringWithCString: nsurl_access(url)]; Website *website = [[Website alloc] initWithName: name - url: [NSURL URLWithString: urlStr]]; + url: urlStr]; [website addToHistory]; [website release]; } diff --git a/frontends/gnustep/HistoryWindowController.h b/frontends/gnustep/HistoryWindowController.h index 735b76be4..5b15deae2 100644 --- a/frontends/gnustep/HistoryWindowController.h +++ b/frontends/gnustep/HistoryWindowController.h @@ -3,7 +3,7 @@ @interface HistoryWindowController: NSWindowController { id outlineView; BOOL ignoreRefresh; - NSMutableDictionary *historyItems; + NSArray *sections; } @end \ No newline at end of file diff --git a/frontends/gnustep/HistoryWindowController.m b/frontends/gnustep/HistoryWindowController.m index 2ab90cc04..8f41d292f 100644 --- a/frontends/gnustep/HistoryWindowController.m +++ b/frontends/gnustep/HistoryWindowController.m @@ -1,28 +1,63 @@ #import + #import "HistoryWindowController.h" #import "Website.h" #import "AppDelegate.h" +#import "desktop/global_history.h" + +@interface Section: NSObject { + NSString *name; + NSArray *items; +} +@end +@implementation Section ++(id)sectionWithName: (NSString*)aName items: (NSArray*)someItems { + Section *section = [[[Section alloc] init] autorelease]; + section->name = [aName retain]; + section->items = [someItems retain]; + return section; +} +-(NSString*)name { + return name; +} +-(NSArray*)items { + return items; +} +-(void)setItems: (NSArray*)someItems { + [items release]; + items = [someItems retain]; +} +-(void)dealloc { + [name release]; + [items release]; + [super dealloc]; +} +@end @implementation HistoryWindowController -(id)init { if (self = [super initWithWindowNibName: @"History"]) { - historyItems = [[NSMutableDictionary alloc] init]; - [historyItems setObject: [Website historicWebsites] forKey: @"recent"]; ignoreRefresh = NO; + sections = [[NSArray arrayWithObjects: [Section sectionWithName: @"Recent" + items: [NSArray array]], [Section sectionWithName: + @"More than 2 months ago..." items: [NSArray array]], nil] + retain]; + [self updateItems: nil]; } return self; } -(void)dealloc { - [historyItems release]; + [sections release]; [super dealloc]; } -(void)updateItems: (NSNotification*)aNotification { if (!ignoreRefresh) { - [historyItems setObject: [Website historicWebsites] forKey: @"recent"]; + [[sections objectAtIndex: 0] setItems: [NSArray array]]; + [[sections objectAtIndex: 1] setItems: [NSArray array]]; [outlineView reloadData]; } } @@ -47,7 +82,7 @@ -(void)awakeFromNib { [[self window] makeKeyAndOrderFront: self]; [self registerForHistoryNotifications]; - [outlineView expandItem: [[historyItems allValues] firstObject] expandChildren: NO]; + [outlineView expandItem: [sections firstObject] expandChildren: NO]; } -(BOOL)validateMenuItem: (NSMenuItem*)aMenuItem { @@ -99,14 +134,14 @@ -(id)outlineView: (NSOutlineView*)outlineView child: (NSInteger)index ofItem: (id)item { if (item == nil) { - return [[historyItems allValues] firstObject]; + return [sections objectAtIndex: index]; } else { - return [item objectAtIndex: index]; + return [[item items] objectAtIndex: index]; } } -(BOOL)outlineView: (NSOutlineView*)outlineView isItemExpandable: (id)item { - if ([item isKindOfClass: [NSArray class]]) { + if ([item isKindOfClass: [Section class]]) { return YES; } else { return NO; @@ -115,20 +150,16 @@ -(NSInteger)outlineView: (NSOutlineView*)outlineView numberOfChildrenOfItem: (id)item { if (item == nil) { - return 1; + return [sections count]; + } else if ([item isKindOfClass: [Section class]]) { + return [[item items] count]; + } else { + return 0; } - return [item count]; } -(id)outlineView: (NSOutlineView*)outlineView objectValueForTableColumn: (NSTableColumn*)tableColumn byItem: (id)item { - if ([item isKindOfClass: [NSArray class]]) { - return @"Recent History"; - } else if ([item isKindOfClass: [Website class]]) { - return [item name]; - } else { - NSLog(@"clas: %@", [item class]); - return @"Error"; - } + return [item name]; } -(BOOL)outlineView: (NSOutlineView*)outlineView shouldSelectItem: (id)item { diff --git a/frontends/gnustep/Website.h b/frontends/gnustep/Website.h index c0455ab3a..87fff7c88 100644 --- a/frontends/gnustep/Website.h +++ b/frontends/gnustep/Website.h @@ -2,21 +2,21 @@ #define WebsiteHistoryUpdatedNotificationName @"WebsiteHistoryUpdatedNotification" +struct website_data { + int len_name; + int len_url; + char data[]; +}; + @class BookmarkFolder; @interface Website: NSObject { - NSString *name; - NSURL *url; - NSDate *lastVisited; + struct website_data *data; } --(id)initWithName: (NSString*)aName url: (NSURL*)aUrl; +-(id)initWithName: (NSString*)aName url: (NSString*)aUrl; -(NSString*)name; --(NSURL*)url; +-(NSString*)url; -(void)open; - -(void)addToHistory; --(void)removeFromHistory; -+(NSArray*)historicWebsites; - @end \ No newline at end of file diff --git a/frontends/gnustep/Website.m b/frontends/gnustep/Website.m index e2913e33b..572138d3a 100644 --- a/frontends/gnustep/Website.m +++ b/frontends/gnustep/Website.m @@ -1,36 +1,50 @@ #import +#import +#import +#import + #import "Website.h" +#import "AppDelegate.h" -#define HISTORY_PATH @".cache/NetSurf" +#define HISTORY_PATH @"/.cache/NetSurf" -static NSMutableArray *history; +static NSMutableArray *recentHistory; +static NSMutableArray *olderHistory; @implementation Website --(id)initWithName: (NSString*)aName url: (NSURL*)aUrl { +-(id)initWithName: (NSString*)aName url: (NSString*)aUrl { if (self = [super init]) { - [aName retain]; - [aUrl retain]; - name = aName; - url = aUrl; - lastVisited = nil; + int nlen = [aName length]; + int urlen = [aUrl length]; + data = malloc(sizeof (struct website_data) + nlen + urlen); + data->len_name = nlen; + data->len_url = urlen; + memcpy(data->data, [aName cString], nlen); + memcpy(data->data + nlen, [aUrl cString], urlen); + } + return self; +} + +-(id)initWithData: (struct website_data*)someData { + if (self = [super init]) { + data = someData; } return self; } -(void)dealloc { - [name release]; - [url release]; - [lastVisited release]; + free(data); [super dealloc]; } -(NSString*)name { - return name; + return [NSString stringWithCString: data->data length: data->len_name]; } --(NSURL*)url { - return url; +-(NSString*)url { + return [NSString stringWithCString: data->data + data->len_name length: + data->len_url]; } -(void)open { @@ -39,90 +53,26 @@ static NSMutableArray *history; // MARK: - History implementation -+(id)websiteWithDictionary: (NSDictionary*)dictionary { - Website *ret = [[[Website alloc] init] autorelease]; - if (ret != nil) { - ret->name = [dictionary objectForKey: @"name"]; - [ret->name retain]; - ret->url = [NSURL URLWithString: [dictionary objectForKey: @"url"]]; - [ret->url retain]; - ret->lastVisited = [NSDate dateWithTimeIntervalSince1970: [[dictionary - objectForKey: @"date"] doubleValue]]; - [ret->lastVisited retain]; - } - return ret; -} - --(NSDictionary*)toDictionary { - return [NSDictionary dictionaryWithObjectsAndKeys: name, @"name", - [url absoluteString], @"url", - [NSNumber numberWithDouble: [lastVisited timeIntervalSince1970]], @"date", - nil]; -} - -+(void)saveHistoryToDisk { - NSLog(@"Save history to disk"); - if (history == nil) { - return; - } - NSError *error = nil; - NSDictionary *attrs = [NSDictionary dictionary]; - BOOL ok = [[NSFileManager defaultManager] createDirectoryAtPath: [NSString - pathWithComponents: [NSArray arrayWithObjects: NSHomeDirectory(), - HISTORY_PATH, nil]] withIntermediateDirectories: YES attributes: attrs - error: &error]; - if (!ok) { - NSLog(@"Error creating cache dir!"); - } - NSMutableArray *toSave = [NSMutableArray array]; - for (NSUInteger i = 0; i < [history count]; i++) { - [toSave addObject: [[history objectAtIndex: i] toDictionary]]; - } - ok = [toSave writeToFile: [NSString pathWithComponents: [NSArray - arrayWithObjects: NSHomeDirectory(), HISTORY_PATH, @"history", nil]] - atomically: YES]; - if (!ok) { - NSLog(@"Failed to save latest history to file"); - } -} - -+(void)initHistoryIfNeeded { - if (history == nil) { - NSArray *historyDicts = [NSMutableArray arrayWithContentsOfFile: - [NSString pathWithComponents: [NSArray arrayWithObjects: - NSHomeDirectory(), HISTORY_PATH, @"history", nil]]]; - history = [[NSMutableArray alloc] init]; - for (NSUInteger i = 0; i < [historyDicts count]; i++) { - [history addObject: [Website websiteWithDictionary: [historyDicts - objectAtIndex: i]]]; - } - [[NSNotificationCenter defaultCenter] addObserver: [self class] - selector: @selector(saveHistoryToDisk) - name: NSApplicationWillTerminateNotification - object: nil]; - } -} - --(void)removeFromHistory { - NSLog(@"remove self from history"); - [history removeObject: self]; - [[NSNotificationCenter defaultCenter] postNotificationName: - WebsiteHistoryUpdatedNotificationName object: nil]; -} - -(void)addToHistory { - [Website initHistoryIfNeeded]; - [lastVisited release]; - lastVisited = [[NSDate alloc] init]; - [history insertObject: self atIndex: 0]; - NSLog(@"Added %@ , %@ to history!", [self name], [self url]); + static NSString *path = nil; + if (path == nil) { + NSCalendarDate *date = [NSCalendarDate calendarDate]; + int month = [date monthOfYear]; + int year = [date yearOfCommonEra]; + path = [[NSString alloc] initWithFormat: @"%@/%@/history_%d_%d", + NSHomeDirectory(), HISTORY_PATH, year, month]; + } + NSLog(@"name: %@", [self name]); + NSLog(@"url: %@", [self url]); + FILE *f = fopen([path cString], "a"); + if (f != NULL) { + int len = sizeof (struct website_data) + data->len_url + data->len_name; + fwrite(data, len, 1, f); + fclose(f); + } + [[NSNotificationCenter defaultCenter] postNotificationName: WebsiteHistoryUpdatedNotificationName object: self]; } -+(NSArray*)historicWebsites { - [Website initHistoryIfNeeded]; - return history; -} - @end \ No newline at end of file