tweak history impl so as not to require opening and resaving history just to append

This commit is contained in:
anthony 2020-12-31 22:55:28 +00:00
parent 8046fb8af2
commit 544ae837d5
7 changed files with 122 additions and 138 deletions

View File

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
@interface AppDelegate: NSResponder<NSApplicationDelegate> {
@private
NSMutableArray *recentHistory;
id downloadsWindowController;
id findPanelController;
id historyWindowController;

View File

@ -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);

View File

@ -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];
}

View File

@ -3,7 +3,7 @@
@interface HistoryWindowController: NSWindowController {
id outlineView;
BOOL ignoreRefresh;
NSMutableDictionary *historyItems;
NSArray *sections;
}
@end

View File

@ -1,28 +1,63 @@
#import <Cocoa/Cocoa.h>
#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 {

View File

@ -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

View File

@ -1,36 +1,50 @@
#import <Cocoa/Cocoa.h>
#import <stdio.h>
#import <string.h>
#import <errno.h>
#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