Allow opening of local files from anywhere, not just the parent of the current dir.

svn path=/trunk/netsurf/; revision=5695
This commit is contained in:
Chris Young 2008-11-15 15:28:17 +00:00
parent da2a89e436
commit d6874d05b1
13 changed files with 268 additions and 69 deletions

View File

@ -231,6 +231,8 @@ Source:Source...
TextNS:Text...
SaveCompNS:Complete...
PDF:PDF...
OpenFile:Open local file...
About:About...
# Edit menu
#

View File

@ -231,6 +231,8 @@ Source:Source...
TextNS:Text...
SaveCompNS:Complete...
PDF:PDF...
OpenFile:Open local file...
About:About...
# Edit menu
#

View File

@ -231,6 +231,8 @@ Source:Source...
TextNS:Text...
SaveCompNS:Complete...
PDF:PDF...
OpenFile:Open local file...
About:About...
# Edit menu
#

View File

@ -232,6 +232,8 @@ Source:Sorgente...
TextNS:Testo...
SaveCompNS:Complete...
PDF:PDF...
OpenFile:Open local file...
About:About...
# Edit menu
#

View File

@ -231,6 +231,8 @@ Source:Source...
TextNS:Text...
SaveCompNS:Complete...
PDF:PDF...
OpenFile:Open local file...
About:About...
# Edit menu
#

View File

@ -1,7 +1,7 @@
/*
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf.
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,15 @@
#include "utils/url.h"
#include <proto/dos.h>
#include <proto/exec.h>
#include "amiga/object.h"
#include <malloc.h>
#include "content/content.h"
#include <time.h>
#include <proto/utility.h>
#include "utils/messages.h"
static struct MinList *ami_file_fetcher_list;
static UBYTE *ami_file_fetcher_buffer = NULL;
/** Information for a single fetch. */
struct ami_file_fetch_info {
@ -34,6 +43,13 @@ struct ami_file_fetch_info {
bool only_2xx; /**< Only HTTP 2xx responses acceptable. */
char *path;
char *url; /**< URL of this fetch. */
bool aborted;
bool locked;
struct nsObject *obj;
int httpcode;
ULONG len;
char *mimetype;
struct cache_data cachedata;
};
static bool ami_fetch_file_initialise(const char *scheme);
@ -75,7 +91,11 @@ void ami_fetch_file_register(void)
bool ami_fetch_file_initialise(const char *scheme)
{
LOG(("Initialise Amiga fetcher for %s", scheme));
return true; /* Always succeeds */
ami_file_fetcher_list = NewObjList();
ami_file_fetcher_buffer = AllocVec(1024,MEMF_PRIVATE);
if(ami_file_fetcher_list && ami_file_fetcher_buffer) return true;
else return false;
}
@ -86,6 +106,8 @@ bool ami_fetch_file_initialise(const char *scheme)
void ami_fetch_file_finalise(const char *scheme)
{
LOG(("Finalise Amiga fetcher %s", scheme));
FreeObjList(ami_file_fetcher_list);
FreeVec(ami_file_fetcher_buffer);
}
@ -124,14 +146,17 @@ void * ami_fetch_file_setup(struct fetch *parent_fetch, const char *url,
fetch->fetch_handle = parent_fetch;
LOG(("fetch %p, url '%s'", fetch, url));
/* construct a new fetch structure */
fetch->fh = 0;
fetch->only_2xx = only_2xx;
// fetch->url = strdup(url);
fetch->path = url_to_path(url);
LOG(("fetch %p, url '%s', path '%s'", fetch, url,fetch->path));
fetch->obj = AddObject(ami_file_fetcher_list,AMINS_FETCHER);
fetch->obj->objstruct = fetch;
return fetch;
}
@ -143,24 +168,38 @@ bool ami_fetch_file_start(void *vfetch)
{
struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vfetch;
fetch->fh = FOpen(fetch->path,MODE_OLDFILE,0);
LOG(("ami file fetcher start"));
if(fetch->fh) return true;
else return false;
fetch->cachedata.req_time = time(NULL);
fetch->cachedata.res_time = time(NULL);
fetch->cachedata.date = 0;
fetch->cachedata.expires = 0;
fetch->cachedata.age = INVALID_AGE;
fetch->cachedata.max_age = 0;
fetch->cachedata.no_cache = true;
fetch->cachedata.etag = NULL;
fetch->cachedata.last_modified = 0;
return true;
}
void ami_fetch_file_abort(void *vf)
{
struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vf;
LOG(("ami file fetcher abort"));
if (fetch->fh) {
FClose(fetch->fh);
fetch->fh = 0;
// f->abort = true;
} else {
fetch->aborted = true;
}
/*
else {
fetch_remove_from_queues(fetch->fetch_handle);
fetch_free(fetch->fetch_handle);
}
*/
}
@ -171,15 +210,24 @@ void ami_fetch_file_abort(void *vf)
void ami_fetch_file_free(void *vf)
{
struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vf;
LOG(("ami file fetcher free %lx",fetch));
if(fetch->fh)
{
FClose(fetch->fh);
}
if(fetch->fh) FClose(fetch->fh);
if(fetch->mimetype) free(fetch->mimetype);
if(fetch->path) free(fetch->path);
FreeVec(fetch);
DelObject(fetch->obj); // delobject frees fetch
}
static void ami_fetch_file_send_callback(fetch_msg msg,
struct ami_file_fetch_info *fetch, const void *data,
unsigned long size)
{
fetch->locked = true;
LOG(("ami file fetcher callback %ld",msg));
fetch_send_callback(msg,fetch->fetch_handle,data,size);
fetch->locked = false;
}
/**
* Do some work on current fetches.
@ -189,5 +237,79 @@ void ami_fetch_file_free(void *vf)
void ami_fetch_file_poll(const char *scheme_ignored)
{
}
struct nsObject *node;
struct nsObject *nnode;
struct ami_file_fetch_info *fetch;
if(IsMinListEmpty(ami_file_fetcher_list)) return;
node = (struct nsObject *)GetHead((struct List *)ami_file_fetcher_list);
do
{
nnode=(struct nsObject *)GetSucc((struct Node *)node);
fetch = (struct ami_file_fetch_info *)node->objstruct;
LOG(("polling %lx",fetch));
if(fetch->locked) continue;
if(!fetch->aborted)
{
if(fetch->fh)
{
ULONG len;
len = FRead(fetch->fh,ami_file_fetcher_buffer,1,1024);
LOG(("fetch %lx read %ld",fetch,len));
ami_fetch_file_send_callback(FETCH_DATA,
fetch,ami_file_fetcher_buffer,len);
if((len<1024) && (!fetch->aborted))
{
ami_fetch_file_send_callback(FETCH_FINISHED,
fetch, &fetch->cachedata, 0);
fetch->aborted = true;
}
}
else
{
fetch->fh = FOpen(fetch->path,MODE_OLDFILE,0);
if(fetch->fh)
{
struct FileInfoBlock fib;
if(ExamineFH(fetch->fh,&fib))
fetch->len = fib.fib_Size;
fetch_set_http_code(fetch->fetch_handle,200);
fetch->mimetype = fetch_mimetype(fetch->path);
LOG(("mimetype %s len %ld",fetch->mimetype,fetch->len));
ami_fetch_file_send_callback(FETCH_TYPE,
fetch, fetch->mimetype, fetch->len);
}
else
{
STRPTR errorstring;
errorstring = ASPrintf("%s %s",messages_get("FileError"),fetch->path);
fetch_set_http_code(fetch->fetch_handle,404);
ami_fetch_file_send_callback(FETCH_ERROR, fetch,
errorstring, 0);
fetch->aborted = true;
FreeVec(errorstring);
}
}
}
if(fetch && fetch->aborted)
{
fetch_remove_from_queues(fetch->fetch_handle);
fetch_free(fetch->fetch_handle);
}
}while(node=nnode);
}

View File

@ -36,8 +36,9 @@ const char *fetch_filetype(const char *unix_path)
STRPTR ttype = NULL;
struct DiskObject *dobj = NULL;
BPTR lock = 0;
struct DataTypeHeader *dth;
struct DataTypeHeader *dth = NULL;
struct DataType *dtn;
BOOL found = FALSE;
/* First try getting a tooltype "MIMETYPE" and use that as the MIME type. Will fail over
to default icons if the file doesn't have a real icon. */
@ -46,16 +47,21 @@ const char *fetch_filetype(const char *unix_path)
TAG_DONE))
{
ttype = FindToolType(dobj->do_ToolTypes, "MIMETYPE");
if(ttype) strcpy(mimetype,ttype);
if(ttype)
{
strcpy(mimetype,ttype);
found = TRUE;
}
FreeDiskObject(dobj);
}
if(!mimetype)
{
/* If that didn't work, have a go at guessing it using datatypes.library. This isn't
accurate - the base names differ from those used by MIME and it relies on the
user having a datatype installed which can handle the file. */
/* If that didn't work, have a go at guessing it using datatypes.library. This isn't
accurate - the base names differ from those used by MIME and it relies on the
user having a datatype installed which can handle the file. */
if(!found)
{
if (lock = Lock (unix_path, ACCESS_READ))
{
if (dtn = ObtainDataTypeA (DTST_FILE, (APTR)lock, NULL))
@ -84,13 +90,14 @@ const char *fetch_filetype(const char *unix_path)
sprintf(mimetype,"video/%s",dth->dth_BaseName);
break;
}
found = TRUE;
ReleaseDataType(dtn);
}
UnLock(lock);
}
}
if(!mimetype) strcpy(mimetype,"text/html"); /* If all else fails */
if(!found) strcpy(mimetype,"text/html"); /* If all else fails */
return mimetype;
}

View File

@ -67,6 +67,7 @@
#include "amiga/clipboard.h"
#include <proto/keymap.h>
#include "amiga/save_complete.h"
#include "amiga/fetch_file.h"
#ifdef WITH_HUBBUB
#include <hubbub/hubbub.h>
@ -243,8 +244,8 @@ void gui_init(int argc, char** argv)
messages_load(lang); // check locale language and read appropriate file
default_stylesheet_url = "file://NetSurf/Resources/default.css"; //"http://www.unsatisfactorysoftware.co.uk/newlook.css"; //path_to_url(buf);
adblock_stylesheet_url = "file://NetSurf/Resources/adblock.css";
default_stylesheet_url = "file:///Resources/default.css"; //"http://www.unsatisfactorysoftware.co.uk/newlook.css"; //path_to_url(buf);
adblock_stylesheet_url = "file:///Resources/adblock.css";
#ifdef WITH_HUBBUB
if(hubbub_initialise("Resources/Aliases",myrealloc,NULL) != HUBBUB_OK)
@ -402,6 +403,8 @@ void gui_init2(int argc, char** argv)
A_URL
};
ami_fetch_file_register();
InitRastPort(&dummyrp);
dummyrp.BitMap = p96AllocBitMap(1,1,32,
BMF_CLEAR | BMF_DISPLAYABLE | BMF_INTERLEAVED,
@ -1195,6 +1198,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
char home[100],home_s[100],home_g[100];
char closetab[100];
if((bw->browser_window_type == BROWSER_WINDOW_IFRAME) && option_no_iframes) return NULL;
if(option_force_tabs && (bw->browser_window_type == BROWSER_WINDOW_NORMAL))
{
/* option_force_tabs reverses the new_tab parameter.
@ -1218,17 +1223,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
}
}
if(bw->browser_window_type == BROWSER_WINDOW_IFRAME)
{
if(option_no_iframes) return NULL;
/*
gwin = bw->parent->window;
printf("%lx\n",gwin);
return gwin;
*/
}
gwin = AllocVec(sizeof(struct gui_window),MEMF_PRIVATE | MEMF_CLEAR);
if(!gwin)
@ -1237,6 +1231,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
return NULL;
}
/*
if(bw->browser_window_type == BROWSER_WINDOW_IFRAME)
{
gwin->shared = bw->parent->window->shared;
gwin->bw = bw;
return gwin;
}
*/
if(new_tab && clone && (bw->browser_window_type == BROWSER_WINDOW_NORMAL))
{
gwin->shared = clone->window->shared;
@ -1968,6 +1971,7 @@ void gui_window_position_frame(struct gui_window *g, int x0, int y0,
int x1, int y1)
{
if(!g) return;
ChangeWindowBox(g->shared->win,x0,y0,x1-x0,y1-y0);
}
@ -2366,6 +2370,7 @@ struct gui_download_window *gui_download_window_create(const char *url,
ASLFR_Screen,scrn,
ASLFR_DoSaveMode,TRUE,
ASLFR_InitialFile,FilePart(url),
ASLFR_InitialDrawer,option_download_dir,
TAG_DONE))
{
strlcpy(&fname,filereq->fr_Drawer,1024);

View File

@ -120,6 +120,7 @@ struct gui_window
int c_h;
int scrollx;
int scrolly;
struct browser_window *bw; // not used
};
void ami_get_msg(void);

View File

@ -60,28 +60,30 @@ void ami_init_menulabs(void)
menulab[1] = ami_utf8_easy((char *)messages_get("NewWindowNS"));
menulab[2] = ami_utf8_easy((char *)messages_get("NewTab"));
menulab[3] = NM_BARLABEL;
menulab[4] = ami_utf8_easy((char *)messages_get("SaveAs"));
menulab[5] = ami_utf8_easy((char *)messages_get("Source"));
menulab[6] = ami_utf8_easy((char *)messages_get("TextNS"));
menulab[7] = ami_utf8_easy((char *)messages_get("SaveCompNS"));
menulab[8] = ami_utf8_easy((char *)messages_get("PDF"));
menulab[9] = NM_BARLABEL;
menulab[10] = ami_utf8_easy((char *)messages_get("CloseTab"));
menulab[11] = ami_utf8_easy((char *)messages_get("CloseWindow"));
menulab[12] = NM_BARLABEL;
menulab[13] = ami_utf8_easy((char *)messages_get("Quit"));
menulab[14] = ami_utf8_easy((char *)messages_get("Edit"));
menulab[15] = ami_utf8_easy((char *)messages_get("CopyNS"));
menulab[16] = ami_utf8_easy((char *)messages_get("Paste"));
menulab[17] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
menulab[18] = ami_utf8_easy((char *)messages_get("ClearNS"));
menulab[19] = ami_utf8_easy((char *)messages_get("Browser"));
menulab[20] = ami_utf8_easy((char *)messages_get("HistGlobalNS"));
menulab[21] = ami_utf8_easy((char *)messages_get("ShowCookies"));
menulab[22] = ami_utf8_easy((char *)messages_get("Hotlist"));
menulab[23] = ami_utf8_easy((char *)messages_get("HotlistAdd"));
menulab[24] = ami_utf8_easy((char *)messages_get("HotlistShowNS"));
menulab[25] = NM_BARLABEL;
menulab[4] = ami_utf8_easy((char *)messages_get("OpenFile"));
menulab[5] = ami_utf8_easy((char *)messages_get("SaveAs"));
menulab[6] = ami_utf8_easy((char *)messages_get("Source"));
menulab[7] = ami_utf8_easy((char *)messages_get("TextNS"));
menulab[8] = ami_utf8_easy((char *)messages_get("SaveCompNS"));
menulab[9] = ami_utf8_easy((char *)messages_get("PDF"));
menulab[10] = NM_BARLABEL;
menulab[11] = ami_utf8_easy((char *)messages_get("CloseTab"));
menulab[12] = ami_utf8_easy((char *)messages_get("CloseWindow"));
menulab[13] = NM_BARLABEL;
menulab[14] = ami_utf8_easy((char *)messages_get("About"));
menulab[15] = ami_utf8_easy((char *)messages_get("Quit"));
menulab[16] = ami_utf8_easy((char *)messages_get("Edit"));
menulab[17] = ami_utf8_easy((char *)messages_get("CopyNS"));
menulab[18] = ami_utf8_easy((char *)messages_get("Paste"));
menulab[19] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
menulab[20] = ami_utf8_easy((char *)messages_get("ClearNS"));
menulab[21] = ami_utf8_easy((char *)messages_get("Browser"));
menulab[22] = ami_utf8_easy((char *)messages_get("HistGlobalNS"));
menulab[23] = ami_utf8_easy((char *)messages_get("ShowCookies"));
menulab[24] = ami_utf8_easy((char *)messages_get("Hotlist"));
menulab[25] = ami_utf8_easy((char *)messages_get("HotlistAdd"));
menulab[26] = ami_utf8_easy((char *)messages_get("HotlistShowNS"));
menulab[27] = NM_BARLABEL;
menulab[AMI_MENU_HOTLIST_MAX] = ami_utf8_easy((char *)messages_get("Settings"));
menulab[AMI_MENU_HOTLIST_MAX+1] = ami_utf8_easy((char *)messages_get("SnapshotWindow"));
@ -100,6 +102,7 @@ struct NewMenu *ami_create_menu(ULONG type)
{ NM_ITEM,0,"N",0,0,0,}, // new window
{ NM_ITEM,0,"T",0,0,0,}, // new tab
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,"O",0,0,0,}, // open local file
{ NM_ITEM,0,0,0,0,0,}, // save
{ NM_SUB,0,"S",0,0,0,}, // save as source
{ NM_SUB,0,0,0,0,0,}, // save as text
@ -109,6 +112,7 @@ struct NewMenu *ami_create_menu(ULONG type)
{ NM_ITEM,0,"K",0,0,0,}, // close tab
{ NM_ITEM,0,0,0,0,0,}, // close window
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,"?",NM_ITEMDISABLED,0,0,}, // about
{ NM_ITEM,0,"Q",0,0,0,}, // quit
{NM_TITLE,0,0,0,0,0,}, // edit
{ NM_ITEM,0,"C",0,0,0,}, // copy
@ -384,7 +388,29 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item)
bw = browser_window_create(gwin->bw->current_content->url,gwin->bw, 0, true, opentab);
break;
case 3: // save
case 3: // open local file
if(AslRequestTags(filereq,
ASLFR_TitleText,messages_get("NetSurf"),
ASLFR_Screen,scrn,
ASLFR_DoSaveMode,FALSE,
// ASLFR_InitialDrawer,option_arexx_dir,
// ASLFR_InitialPattern,"#?.html",
TAG_DONE))
{
if(temp = AllocVec(1024,MEMF_PRIVATE | MEMF_CLEAR))
{
char *temp2;
strlcpy(temp,filereq->fr_Drawer,1024);
AddPart(temp,filereq->fr_File,1024);
temp2 = path_to_url(temp);
browser_window_go(gwin->bw,temp2,NULL, true);
free(temp2);
FreeVec(temp);
}
}
break;
case 4: // save
switch(subnum)
{
BPTR fh=0;
@ -471,15 +497,19 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item)
}
break;
case 5: // close tab
case 6: // close tab
browser_window_destroy(gwin->bw);
break;
case 6: // close window
case 7: // close window
ami_close_all_tabs(gwin);
break;
case 8: // quit
case 9: // about
// do nothing
break;
case 10: // quit
ami_quit_netsurf();
break;
}

View File

@ -28,10 +28,10 @@
/* Maximum number of menu items - first value is number of static items
* (ie. everything not intially defined as NM_IGNORE) */
#define AMI_MENU_MAX 32 + AMI_HOTLIST_ITEMS
#define AMI_MENU_MAX 34 + AMI_HOTLIST_ITEMS
/* Where the hotlist entries start */
#define AMI_MENU_HOTLIST 26
#define AMI_MENU_HOTLIST 28
/* Where the hotlist entries end */
#define AMI_MENU_HOTLIST_MAX AMI_MENU_HOTLIST+AMI_HOTLIST_ITEMS

View File

@ -1,5 +1,4 @@
/*
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
@ -24,6 +23,7 @@
#include <proto/dos.h>
#include "utils/messages.h"
#include <stdlib.h>
#include <curl/curl.h>
void warn_user(const char *warning, const char *detail)
{
@ -51,14 +51,36 @@ void die(const char *error)
char *url_to_path(const char *url)
{
return (char *)strdup(url + 5);
char *tmps,*unesc;
CURL *curl;
if(tmps = strchr(url,'/'))
{
if(tmps = strchr(tmps+1,'/'))
{
if(tmps = strchr(tmps+1,'/'))
{
if(curl = curl_easy_init())
{
unesc = curl_easy_unescape(curl,tmps+1,0,NULL);
tmps = strdup(unesc);
curl_free(unesc);
curl_easy_cleanup(curl);
return tmps;
}
}
}
}
return strdup((char *)url);
}
char *path_to_url(const char *path)
{
char *r = malloc(strlen(path) + 7 + 1);
char *r = malloc(strlen(path) + 8 + 1);
strcpy(r, "file://");
strcpy(r, "file:///");
strcat(r, path);
return r;

View File

@ -23,12 +23,14 @@
enum
{
AMINS_UNKNOWN,
AMINS_CALLBACK,
AMINS_WINDOW,
AMINS_FRAME,
AMINS_DLWINDOW,
AMINS_LOGINWINDOW,
AMINS_TVWINDOW
AMINS_TVWINDOW,
AMINS_FETCHER,
};
struct nsObject