Merge treeview-redux to trunk

svn path=/trunk/netsurf/; revision=10865
This commit is contained in:
John Mark Bell 2010-10-05 19:14:46 +00:00
parent 195c1ea319
commit 6173bb0e6c
109 changed files with 11511 additions and 7946 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

View File

@ -189,6 +189,8 @@ ResetUsage:Statistik zurücksetzen
New:Neu
Expand:Expandieren
Collapse:Zusammenfalten
Tree:Tree
TreeExport:Export...
# New hotlist entry menu
#
@ -200,6 +202,7 @@ Link:Eintrag
All:Alles
Folders:Verzeichnisse
Links:Einträge
Domains:Domains
# Other menus
#
@ -373,6 +376,13 @@ DateYesterday:Gestern
Date1Week:vorige Woche
Date2Week:vor 2 Wochen
Date3Week:vor 3 Wochen
Sunday:Sunday
Monday:Monday
Tuesday:Tuesday
Wednesday:Wednesday
Thursday:Thursday
Friday:Friday
Saturday:Saturday
# Download user interface tokens

View File

@ -189,6 +189,8 @@ ResetUsage:Reset statistics
New:New
Expand:Expand
Collapse:Collapse
Tree:Tree
TreeExport:Export...
# New hotlist entry menu
#
@ -200,6 +202,7 @@ Link:Address
All:All
Folders:Directories
Links:Addresses
Domains:Domains
# Other menus
#
@ -332,6 +335,7 @@ TreeNewFolder:New directory
TreeLaunch:Visit URL
TreeDelete:Delete
# Tree export
#
TreeHotlist:NetSurf hotlist
@ -374,6 +378,13 @@ DateYesterday:Yesterday
Date1Week:Last week
Date2Week:2 weeks ago
Date3Week:3 weeks ago
Sunday:Sunday
Monday:Monday
Tuesday:Tuesday
Wednesday:Wednesday
Thursday:Thursday
Friday:Friday
Saturday:Saturday
# Download user interface tokens
@ -534,6 +545,8 @@ gtkGlobalHistoryAccel:<ctrl><shift>h
gtkAddBookMarks:_Add to Bookmarks…
gtkShowBookMarks:_Show Bookmarks…
gtkShowBookMarksAccel:F6
gtkShowCookies:Show _Cookies…
gtkShowCookiesAccel:F9
gtkOpenLocation:_Open Location…
gtkOpenLocationAccel:<ctrl>l
@ -607,15 +620,15 @@ Cancel:Cancel
#
SSLCerts:SSL certificates
SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.
Subject:Subject
Issuer:Issuer
Version:Version
ValidFrom:Valid from
ValidTo:Valid until
Type:Type
Serial:Serial
Accept:Accept
Reject:Reject
SSL_Certificate_Subject:Subject: %s
SSL_Certificate_Issuer:Issuer: %s
SSL_Certificate_Version:Version: %ld
SSL_Certificate_ValidFrom:Valid from: %s
SSL_Certificate_ValidTo:Valid until: %s
SSL_Certificate_Type:Type: %i
SSL_Certificate_Serial:Serial: %ld
SSL_Certificate_Accept:Accept
SSL_Certificate_Reject:Reject
# Content
@ -723,7 +736,7 @@ Resolvers:No domain name servers are configured, so only browsing local files wi
NoDiscSpace:Not enough space available on disc.
Template:A window template is missing from the Templates file. Please reinstall NetSurf.
HotlistSaveError:The hotlist was unable to be correctly saved.
HotlistLoadError:The hotlist was unable to be correctly loaded.
TreeLoadError:The tree was unable to be correctly loaded.
NoDirError:%s is not a directory
NoPathError:To save, drag the icon to a directory display
NoNameError:Please enter a name

View File

@ -189,6 +189,8 @@ ResetUsage:RAZ des statistiques
New:Nouveau
Expand:Déployer
Collapse:Regrouper
Tree:Tree
TreeExport:Export...
# New hotlist entry menu
#
@ -200,6 +202,7 @@ Link:Adresse
All:Tout
Folders:Dossiers
Links:Adresses
Domains:Domains
# Other menus
#
@ -373,6 +376,13 @@ DateYesterday:Hier
Date1Week:La semaine dernière
Date2Week:Il y a 2 semaines
Date3Week:Il y a 3 semaines
Sunday:Sunday
Monday:Monday
Tuesday:Tuesday
Wednesday:Wednesday
Thursday:Thursday
Friday:Friday
Saturday:Saturday
# Download user interface tokens

View File

@ -191,6 +191,8 @@ ResetUsage:Resetta statistiche
New:Nuovo
Expand:Espandi
Collapse:Raggruppa
Tree:Tree
TreeExport:Export...
# New hotlist entry menu
#
@ -202,6 +204,7 @@ Link:Indirizzo
All:Tutte
Folders:Cartelle
Links:Indirizzi
Domains:Domains
# Other menus
#
@ -375,6 +378,13 @@ DateYesterday:Ieri
Date1Week:Ultima settimana
Date2Week:2 settimane fa
Date3Week:3 settimane fa
Sunday:Sunday
Monday:Monday
Tuesday:Tuesday
Wednesday:Wednesday
Thursday:Thursday
Friday:Friday
Saturday:Saturday
# Download user interface tokens

View File

@ -189,6 +189,8 @@ ResetUsage:Statistiek op nul zetten
New:Nieuw
Expand:Uitklappen
Collapse:Inklappen
Tree:Tree
TreeExport:Export...
# New hotlist entry menu
#
@ -200,6 +202,7 @@ Link:Adres
All:Alles
Folders:Mappen
Links:Adressen
Domains:Domains
# Other menus
#
@ -373,6 +376,13 @@ DateYesterday:gisteren
Date1Week:vorige week
Date2Week:2 weken geleden
Date3Week:3 weken geleden
Sunday:Sunday
Monday:Monday
Tuesday:Tuesday
Wednesday:Wednesday
Thursday:Thursday
Friday:Friday
Saturday:Saturday
# Download user interface tokens

View File

@ -13,8 +13,9 @@ S_RENDER := box.c box_construct.c box_normalise.c favicon.c \
hubbub_binding.c imagemap.c layout.c list.c table.c textplain.c
S_UTILS := base64.c filename.c hashtable.c http.c locale.c messages.c \
talloc.c url.c utf8.c utils.c useragent.c findresource.c
S_DESKTOP := knockout.c options.c plot_style.c print.c search.c \
searchweb.c scroll.c textarea.c tree.c version.c
S_DESKTOP := cookies.c history_global_core.c hotlist.c knockout.c \
options.c plot_style.c print.c search.c searchweb.c scroll.c \
sslcert.c textarea.c tree.c tree_url_node.c version.c \
# S_COMMON are sources common to all builds
S_COMMON := $(addprefix content/,$(S_CONTENT)) \
@ -47,7 +48,7 @@ S_RISCOS := 401login.c artworks.c assert.c awrender.s bitmap.c buffer.c \
schedule.c search.c searchweb.c sprite.c sslcert.c \
textarea.c textselection.c theme.c theme_install.c thumbnail.c \
treeview.c ucstables.c uri.c url_complete.c url_protocol.c \
wimp.c wimp_event.c window.c gui/progress_bar.c \
url_suggest.c wimp.c wimp_event.c window.c gui/progress_bar.c \
gui/status_bar.c \
$(addprefix configure/,con_cache.c con_connect.c con_content.c \
con_fonts.c con_home.c con_image.c con_inter.c con_language.c \
@ -62,22 +63,22 @@ S_GTK := font_pango.c gtk_bitmap.c gtk_gui.c gtk_schedule.c \
gtk_completion.c gtk_login.c gtk_throbber.c gtk_selection.c \
gtk_history.c gtk_window.c gtk_filetype.c gtk_download.c \
gtk_menu.c gtk_print.c gtk_save.c gtk_search.c gtk_tabs.c \
gtk_theme.c gtk_toolbar.c sexy_icon_entry.c gtk_compat.c \
gtk_theme.c gtk_toolbar.c sexy_icon_entry.c gtk_compat.c \
gtk_cookies.c gtk_hotlist.c \
$(addprefix dialogs/,gtk_options.c gtk_about.c gtk_source.c)
S_GTK := $(addprefix gtk/,$(S_GTK)) $(addprefix utils/,container.c)
# code in utils/container.ch is non-universal it seems
# S_WINDOWS are sources purely for the windows build
S_WINDOWS := about.c bitmap.c download.c filetype.c findfile.c font.c \
gui.c history.c hotlist.c localhistory.c login.c misc.c plot.c \
prefs.c schedule.c thumbnail.c tree.c
S_WINDOWS := about.c bitmap.c download.c filetype.c findfile.c font.c \
gui.c localhistory.c login.c misc.c plot.c prefs.c schedule.c \
thumbnail.c tree.c
S_WINDOWS := $(addprefix windows/,$(S_WINDOWS))
# S_BEOS are sources purely for the BeOS build
S_BEOS := beos_about.cpp beos_bitmap.cpp beos_fetch_rsrc.cpp \
beos_filetype.cpp beos_font.cpp beos_gui.cpp beos_history.cpp \
beos_login.cpp beos_options.cpp beos_plotters.cpp \
beos_save_complete.cpp \
beos_filetype.cpp beos_font.cpp beos_gui.cpp beos_login.cpp \
beos_options.cpp beos_plotters.cpp beos_save_complete.cpp \
beos_scaffolding.cpp beos_search.cpp beos_schedule.cpp \
beos_thumbnail.cpp beos_treeview.cpp beos_throbber.cpp \
beos_window.cpp
@ -102,9 +103,9 @@ S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
# S_FRAMEBUFFER are sources purely for the framebuffer build
S_FRAMEBUFFER := gui.c framebuffer.c tree.c history.c hotlist.c \
save.c schedule.c thumbnail.c misc.c bitmap.c filetype.c \
login.c findfile.c localhistory.c
S_FRAMEBUFFER := gui.c framebuffer.c tree.c save.c schedule.c \
thumbnail.c misc.c bitmap.c filetype.c login.c findfile.c \
localhistory.c
S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \
text.c scroll.c osk.c

View File

@ -1,6 +1,5 @@
/*
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -17,151 +16,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Cookies (implementation).
*/
#include <string.h>
#include "content/urldb.h"
#include "desktop/cookies.h"
#include "desktop/tree.h"
#include "utils/messages.h"
#include "utils/log.h"
#include "amiga/cookies.h"
#include <proto/exec.h>
#include <assert.h>
#include "utils/utils.h"
#include "amiga/cookies.h"
#include "desktop/cookies.h"
#include "amiga/tree.h"
static bool cookies_init;
struct node *ami_cookies_find(const char *url);
/**
* Initialise cookies tree
*/
void ami_cookies_initialise(void)
{
if(cookies_tree) return;
cookies_window = ami_tree_create(cookies_get_tree_flags(), NULL);
/* Create an empty tree */
cookies_tree = AllocVec(sizeof(struct tree),MEMF_CLEAR | MEMF_PRIVATE);
if (!cookies_tree) {
warn_user("NoMemory", 0);
return;
}
cookies_tree->root = tree_create_folder_node(NULL, "Root");
if (!cookies_tree->root) {
warn_user("NoMemory", 0);
FreeVec(cookies_tree);
cookies_tree = NULL;
}
cookies_tree->root->expanded = true;
cookies_tree->movable = false;
cookies_tree->no_drag = true;
if(!cookies_window) return;
cookies_init = true;
urldb_iterate_cookies(cookies_update);
cookies_init = false;
tree_initialise(cookies_tree);
}
/**
* Perform cookie addition
*
* \param data Cookie data for a domain, or NULL
* \return true (for urldb_iterate_entries)
*/
bool cookies_update(const char *domain, const struct cookie_data *data)
{
struct node *parent;
struct node *node = NULL;
struct node *child;
struct node *add;
const struct cookie_data *cookie = NULL;
bool expanded;
assert(domain);
/* check if we're a domain, and add get the first cookie */
if (data)
for (cookie = data; cookie->prev; cookie = cookie->prev);
if (!cookies_init) {
node = ami_cookies_find(domain);
if (node) {
/* mark as deleted so we don't remove the cookies */
expanded = node->expanded;
for (child = node->child; child; child = child->next)
child->deleted = true;
if (node->child)
tree_delete_node(cookies_tree, node->child,
true);
/* deleting will have contracted our node */
node->expanded = expanded;
}
if (!data) {
if (!node)
return true;
tree_delete_node(cookies_tree, node, false);
tree_handle_node_changed(cookies_tree,
cookies_tree->root, true, false);
return true;
}
}
if (!node) {
for (parent = cookies_tree->root->child; parent;
parent = parent->next) {
if (strcmp(domain, parent->data.text) == 0)
break;
}
if (!parent) {
node = tree_create_folder_node(cookies_tree->root,
domain);
} else {
node = parent;
}
}
if (!node)
return true;
node->editable = false;
for (; cookie; cookie = cookie->next) {
add = tree_create_cookie_node(node, cookie);
if (add && !cookies_init)
tree_handle_node_changed(cookies_tree, add,
true, false);
}
if (!cookies_init) {
tree_handle_node_changed(cookies_tree, node,
true, false);
/*
tree_redraw_area(cookies_tree,
node->box.x - NODE_INSTEP,
0, NODE_INSTEP, 16384);
*/
}
return true;
}
/**
* Find an entry in the cookie tree
*
* \param url The URL to find
* \return Pointer to node, or NULL if not found
*/
struct node *ami_cookies_find(const char *url)
{
struct node *node;
for (node = cookies_tree->root->child; node; node = node->next) {
if (!strcmp(url, node->data.text))
return node;
}
return NULL;
cookies_initialise(ami_tree_get_tree(cookies_window));
}
void ami_cookies_free()
{
FreeVec(cookies_tree);
cookies_cleanup();
ami_tree_destroy(cookies_window);
cookies_window = NULL;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -19,9 +19,10 @@
#ifndef AMIGA_COOKIES_H
#define AMIGA_COOKIES_H
#include "desktop/tree.h"
#include "amiga/tree.h"
void ami_cookies_initialise(void);
void ami_cookies_free(void);
struct tree *cookies_tree;
struct treeview_window *cookies_window;
#endif

View File

@ -143,6 +143,8 @@ BOOL screen_closed = FALSE;
struct MsgPort *applibport = NULL;
ULONG applibsig = 0;
const char tree_directory_icon_name[100];
const char tree_content_icon_name[100];
extern colour scroll_widget_fg_colour;
extern colour scroll_widget_bg_colour;
extern colour scroll_widget_arrow_colour;
@ -324,9 +326,6 @@ void ami_set_options(void)
if((!option_url_file) || (option_url_file[0] == '\0'))
option_url_file = (char *)strdup("PROGDIR:Resources/URLs");
if((!option_recent_file) || (option_recent_file[0] == '\0'))
option_recent_file = (char *)strdup("PROGDIR:Resources/Recent");
/*
if((!option_cookie_jar) || (option_cookie_jar[0] == '\0'))
option_cookie_jar = (char *)strdup("PROGDIR:Resources/CookieJar");
@ -453,7 +452,6 @@ void gui_init(int argc, char** argv)
plot=amiplot;
ami_init_menulabs();
if(option_context_menu) ami_context_menu_init();
schedule_list = NewObjList();
@ -462,15 +460,6 @@ void gui_init(int argc, char** argv)
urldb_load(option_url_file);
urldb_load_cookies(option_cookie_file);
if(lock = Lock(option_hotlist_file,SHARED_LOCK))
{
UnLock(lock);
hotlist = options_load_tree(option_hotlist_file);
}
if(!hotlist) ami_hotlist_init(&hotlist);
ami_global_history_initialise();
ami_cookies_initialise();
save_complete_init();
ami_theme_init();
ami_init_mouse_pointers();
@ -567,6 +556,18 @@ static void gui_init2(int argc, char** argv)
notalreadyrunning = ami_arexx_init();
/* Treeview init code ends up calling a font function which needs this */
browserglob.scale = 1.0;
glob = &browserglob;
/**/
ami_get_theme_filename(&tree_directory_icon_name,"theme_list_folder",true);
ami_get_theme_filename(&tree_content_icon_name,"theme_list_content",true);
ami_hotlist_initialise(option_hotlist_file);
ami_cookies_initialise();
ami_global_history_initialise();
sslcert_init();
search_web_provider_details(option_search_provider);
if(argc) // argc==0 is started from wb
@ -1331,7 +1332,7 @@ void ami_handle_msg(void)
case 'h':
if((option_kiosk_mode == false) &&
(gwin->bw->browser_window_type == BROWSER_WINDOW_NORMAL))
ami_open_tree(hotlist,AMI_TREE_HOTLIST);
ami_tree_open(hotlist_window, AMI_TREE_HOTLIST);
break;
/* The following aren't available from the menu at the moment */
@ -2002,11 +2003,10 @@ void gui_quit(void)
urldb_save(option_url_file);
urldb_save_cookies(option_cookie_file);
options_save_tree(hotlist,option_hotlist_file,messages_get("TreeHotlist"));
void ami_global_history_save();
ami_hotlist_free(option_hotlist_file);
ami_cookies_free();
ami_global_history_free();
sslcert_cleanup();
hubbub_finalise(ns_realloc,NULL);
@ -2033,7 +2033,10 @@ void gui_quit(void)
FreeVec(nsscreentitle);
if(option_context_menu) ami_context_menu_free();
ami_free_menulabs();
/* fixme: need newmenu struct propd to this function - should this be freed here?
ami_free_menulabs(menu);
*/
ami_mouse_pointers_free();
ami_clipboard_free();
@ -2187,7 +2190,6 @@ void ami_toggletabbar(struct gui_window_2 *gwin, bool show)
struct gui_window *gui_create_browser_window(struct browser_window *bw,
struct browser_window *clone, bool new_tab)
{
struct NewMenu *menu;
struct gui_window *gwin = NULL;
bool closegadg=TRUE;
struct Node *node;
@ -2357,7 +2359,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
{
ULONG addtabclosegadget = TAG_IGNORE;
menu = ami_create_menu(bw->browser_window_type);
ami_create_menu(bw->browser_window_type, gwin->shared);
NewList(&gwin->shared->tab_list);
gwin->tab_node = AllocClickTabNode(TNA_Text,messages_get("NetSurf"),
@ -2389,28 +2391,28 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
gwin->shared->helphints[GID_ADDTAB] =
remove_escape_chars(messages_get("HelpAddTab"), true);
ami_get_theme_filename(nav_west,"theme_nav_west");
ami_get_theme_filename(nav_west_s,"theme_nav_west_s");
ami_get_theme_filename(nav_west_g,"theme_nav_west_g");
ami_get_theme_filename(nav_east,"theme_nav_east");
ami_get_theme_filename(nav_east_s,"theme_nav_east_s");
ami_get_theme_filename(nav_east_g,"theme_nav_east_g");
ami_get_theme_filename(stop,"theme_stop");
ami_get_theme_filename(stop_s,"theme_stop_s");
ami_get_theme_filename(stop_g,"theme_stop_g");
ami_get_theme_filename(reload,"theme_reload");
ami_get_theme_filename(reload_s,"theme_reload_s");
ami_get_theme_filename(reload_g,"theme_reload_g");
ami_get_theme_filename(home,"theme_home");
ami_get_theme_filename(home_s,"theme_home_s");
ami_get_theme_filename(home_g,"theme_home_g");
ami_get_theme_filename(closetab,"theme_closetab");
ami_get_theme_filename(closetab_s,"theme_closetab_s");
ami_get_theme_filename(closetab_g,"theme_closetab_g");
ami_get_theme_filename(addtab,"theme_addtab");
ami_get_theme_filename(addtab_s,"theme_addtab_s");
ami_get_theme_filename(addtab_g,"theme_addtab_g");
ami_get_theme_filename(tabthrobber,"theme_tab_loading");
ami_get_theme_filename(nav_west,"theme_nav_west",false);
ami_get_theme_filename(nav_west_s,"theme_nav_west_s",false);
ami_get_theme_filename(nav_west_g,"theme_nav_west_g",false);
ami_get_theme_filename(nav_east,"theme_nav_east",false);
ami_get_theme_filename(nav_east_s,"theme_nav_east_s",false);
ami_get_theme_filename(nav_east_g,"theme_nav_east_g",false);
ami_get_theme_filename(stop,"theme_stop",false);
ami_get_theme_filename(stop_s,"theme_stop_s",false);
ami_get_theme_filename(stop_g,"theme_stop_g",false);
ami_get_theme_filename(reload,"theme_reload",false);
ami_get_theme_filename(reload_s,"theme_reload_s",false);
ami_get_theme_filename(reload_g,"theme_reload_g",false);
ami_get_theme_filename(home,"theme_home",false);
ami_get_theme_filename(home_s,"theme_home_s",false);
ami_get_theme_filename(home_g,"theme_home_g",false);
ami_get_theme_filename(closetab,"theme_closetab",false);
ami_get_theme_filename(closetab_s,"theme_closetab_s",false);
ami_get_theme_filename(closetab_g,"theme_closetab_g",false);
ami_get_theme_filename(addtab,"theme_addtab",false);
ami_get_theme_filename(addtab_s,"theme_addtab_s",false);
ami_get_theme_filename(addtab_g,"theme_addtab_g",false);
ami_get_theme_filename(tabthrobber,"theme_tab_loading",false);
gwin->shared->objects[GID_ADDTAB_BM] = BitMapObject,
BITMAP_SourceFile, addtab,
@ -2482,7 +2484,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
IDCMP_ACTIVEWINDOW | IDCMP_INTUITICKS |
IDCMP_EXTENDEDMOUSE | IDCMP_GADGETDOWN,
WINDOW_NewMenu,menu,
WINDOW_NewMenu, gwin->shared->menu,
WINDOW_VertProp,1,
WINDOW_IDCMPHook,&gwin->shared->scrollerhook,
WINDOW_IDCMPHookBits,IDCMP_IDCMPUPDATE |
@ -2934,6 +2936,7 @@ void gui_window_destroy(struct gui_window *g)
DisposeObject(g->shared->objects[OID_MAIN]);
ami_free_menulabs(g->shared);
free(g->shared->wintitle);
ami_utf8_free(g->shared->status);
FreeVec(g->shared->svbuffer);

View File

@ -23,8 +23,10 @@
#include <intuition/classusr.h>
#include "desktop/browser.h"
#include <dos/dos.h>
#include <devices/inputevent.h>
#include "desktop/gui.h"
#include "amiga/plotters.h"
#include "amiga/menu.h"
enum
{
@ -56,11 +58,7 @@ enum
GID_PASS,
GID_LOGIN,
GID_CANCEL,
GID_TREEBROWSER,
GID_OPEN,
GID_LEFT,
GID_UP,
GID_DOWN,
GID_NEWF,
GID_NEWB,
GID_DEL,
@ -98,6 +96,11 @@ struct gui_window_2 {
ULONG oldv;
bool redraw_scroll;
bool new_content;
char *menulab[AMI_MENU_AREXX_MAX + 1];
char menukey[AMI_MENU_AREXX_MAX + 1];
UBYTE *menutype;
struct NewMenu *menu;
ULONG hotlist_items;
char *svbuffer;
char *status;
char *wintitle;
@ -127,6 +130,7 @@ void ami_close_all_tabs(struct gui_window_2 *gwin);
void ami_quit_netsurf(void);
void ami_do_redraw(struct gui_window_2 *g);
STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
struct box *ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
struct gui_window_2 *ami_window_at_pointer(void);

View File

@ -1,6 +1,5 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -17,362 +16,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/browser.h"
#include "amiga/history.h"
#include "amiga/tree.h"
#include "content/urldb.h"
#include <proto/dos.h>
#include "amiga/options.h"
#include "desktop/history_global_core.h"
#include <proto/exec.h>
#include <assert.h>
#include <utils/log.h>
#define MAXIMUM_URL_LENGTH 1024
#define MAXIMUM_BASE_NODES 16
static struct node *global_history_base_node[MAXIMUM_BASE_NODES];
static int global_history_base_node_time[MAXIMUM_BASE_NODES];
static int global_history_base_node_count = 0;
static char *global_history_recent_url[GLOBAL_HISTORY_RECENT_URLS];
static int global_history_recent_count = 0;
static bool global_history_init;
static struct node *ami_global_history_find(const char *url);
static bool global_history_add_internal(const char *url,
const struct url_data *data);
void ami_global_history_initialise_node(const char *title,
time_t base, int days_back);
void ami_global_history_initialise_nodes(void);
#include "amiga/tree.h"
void ami_global_history_initialise(void)
{
char s[MAXIMUM_URL_LENGTH];
BPTR *fp;
global_history_window = ami_tree_create(history_global_get_tree_flags(), NULL);
// if(global_history_tree) return;
if(!global_history_window) return;
/* Create an empty tree */
global_history_tree = AllocVec(sizeof(struct tree), MEMF_CLEAR | MEMF_PRIVATE);
if (!global_history_tree) {
warn_user("NoMemory", 0);
return;
}
global_history_tree->root = tree_create_folder_node(NULL, "Root");
if (!global_history_tree->root) {
warn_user("NoMemory", 0);
FreeVec(global_history_tree);
global_history_tree = NULL;
}
global_history_tree->root->expanded = true;
ami_global_history_initialise_nodes();
global_history_tree->movable = false;
/* load recent URLs */
fp = FOpen(option_recent_file, MODE_OLDFILE,0);
if (!fp)
LOG(("Failed to open file '%s' for reading",
option_recent_file));
else {
while (FGets(fp,s, MAXIMUM_URL_LENGTH)) {
if (s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = '\0';
global_history_add_recent(s);
}
FClose(fp);
}
global_history_init = true;
urldb_iterate_entries(global_history_add_internal);
global_history_init = false;
tree_initialise(global_history_tree);
}
void global_history_add(const char *url)
{
const struct url_data *data;
data = urldb_get_url_data(url);
if (!data)
return;
global_history_add_internal(url, data);
}
/**
* Internal routine to actually perform global history addition
*
* \param url The URL to add
* \param data URL data associated with URL
* \return true (for urldb_iterate_entries)
*/
bool global_history_add_internal(const char *url,
const struct url_data *data)
{
int i, j;
struct node *parent = NULL;
struct node *link;
struct node *node;
bool before = false;
int visit_date;
assert(url && data);
visit_date = data->last_visit;
/* find parent node */
for (i = 0; i < global_history_base_node_count; i++) {
if (global_history_base_node_time[i] <= visit_date) {
parent = global_history_base_node[i];
break;
}
}
/* the entry is too old to care about */
if (!parent)
return true;
if (parent->deleted) {
/* parent was deleted, so find place to insert it */
link = global_history_tree->root;
for (j = global_history_base_node_count - 1; j >= 0; j--) {
if (!global_history_base_node[j]->deleted &&
global_history_base_node_time[j] >
global_history_base_node_time[i]) {
link = global_history_base_node[j];
before = true;
break;
}
}
tree_set_node_selected(global_history_tree,
parent, false);
tree_set_node_expanded(global_history_tree,
parent, false);
tree_link_node(link, parent, before);
/*
if (!global_history_init) {
tree_recalculate_node(global_history_tree, parent, true);
tree_recalculate_node_positions(global_history_tree,
global_history_tree->root);
tree_redraw_area(global_history_tree,
0, 0, 16384, 16384);
}
*/
}
/* find any previous occurance */
if (!global_history_init) {
node = ami_global_history_find(url);
if (node) {
/* \todo: calculate old/new positions and redraw
* only the relevant portion */
/*
tree_redraw_area(global_history_tree,
0, 0, 16384, 16384);
*/
tree_update_URL_node(node, url, data);
tree_delink_node(node);
tree_link_node(parent, node, false);
tree_handle_node_changed(global_history_tree,
node, false, true);
return true;
}
}
/* Add the node at the bottom */
node = tree_create_URL_node_shared(parent, url, data);
if ((!global_history_init) && (node)) {
/*
tree_redraw_area(global_history_tree,
node->box.x - NODE_INSTEP,
0, NODE_INSTEP, 16384);
*/
tree_handle_node_changed(global_history_tree, node,
true, false);
}
return true;
}
/**
* Find an entry in the global history
*
* \param url The URL to find
* \return Pointer to node, or NULL if not found
*/
struct node *ami_global_history_find(const char *url)
{
int i;
struct node *node;
struct node_element *element;
for (i = 0; i < global_history_base_node_count; i++) {
if (!global_history_base_node[i]->deleted) {
for (node = global_history_base_node[i]->child;
node; node = node->next) {
element = tree_find_element(node,
TREE_ELEMENT_URL);
if ((element) && !strcmp(url, element->text))
return node;
}
}
}
return NULL;
}
/**
* Saves the global history's recent URL data.
*/
void ami_global_history_save(void)
{
BPTR *fp;
int i;
/* save recent URLs */
fp = fopen(option_recent_file, "w");
if (!fp)
LOG(("Failed to open file '%s' for writing",
option_recent_file));
else {
for (i = global_history_recent_count - 1; i >= 0; i--)
if (strlen(global_history_recent_url[i]) <
MAXIMUM_URL_LENGTH)
fprintf(fp, "%s\n",
global_history_recent_url[i]);
fclose(fp);
}
}
void global_history_add_recent(const char *url)
{
int i;
int j = -1;
char *current;
/* try to find a string already there */
for (i = 0; i < global_history_recent_count; i++)
if (global_history_recent_url[i] &&
!strcmp(global_history_recent_url[i], url))
j = i;
/* already at head of list */
if (j == 0)
return;
if (j < 0) {
/* add to head of list */
free(global_history_recent_url[
GLOBAL_HISTORY_RECENT_URLS - 1]);
memmove(&global_history_recent_url[1],
&global_history_recent_url[0],
(GLOBAL_HISTORY_RECENT_URLS - 1) *
sizeof(char *));
global_history_recent_url[0] = strdup(url);
global_history_recent_count++;
if (global_history_recent_count > GLOBAL_HISTORY_RECENT_URLS)
global_history_recent_count =
GLOBAL_HISTORY_RECENT_URLS;
/*
if (global_history_recent_count == 1)
ro_gui_window_prepare_navigate_all();
*/
} else {
/* move to head of list */
current = global_history_recent_url[j];
for (i = j; i > 0; i--)
global_history_recent_url[i] =
global_history_recent_url[i - 1];
global_history_recent_url[0] = current;
}
}
/**
* Gets details of the currently used URL list.
*
* \param count set to the current number of entries in the URL array on exit
* \return the current URL array
*/
char **global_history_get_recent(int *count)
{
*count = global_history_recent_count;
return global_history_recent_url;
history_global_initialise(ami_tree_get_tree(global_history_window));
}
void ami_global_history_free()
{
FreeVec(global_history_tree);
history_global_cleanup();
ami_tree_destroy(global_history_window);
global_history_window = NULL;
}
/**
* Initialises the base nodes
*/
void ami_global_history_initialise_nodes(void)
{
struct tm *full_time;
time_t t;
int weekday;
int i;
/* get the current time */
t = time(NULL);
if (t == -1)
return;
/* get the time at the start of today */
full_time = localtime(&t);
weekday = full_time->tm_wday;
full_time->tm_sec = 0;
full_time->tm_min = 0;
full_time->tm_hour = 0;
t = mktime(full_time);
if (t == -1)
return;
ami_global_history_initialise_node((char *)messages_get("DateToday"), t, 0);
if (weekday > 0)
ami_global_history_initialise_node(
(char *)messages_get("DateYesterday"), t, -1);
for (i = 2; i <= weekday; i++)
ami_global_history_initialise_node(NULL, t, -i);
ami_global_history_initialise_node((char *)messages_get("Date1Week"),
t, -weekday - 7);
ami_global_history_initialise_node((char *)messages_get("Date2Week"),
t, -weekday - 14);
ami_global_history_initialise_node((char *)messages_get("Date3Week"),
t, -weekday - 21);
}
/**
* Create and initialise a node
*/
void ami_global_history_initialise_node(const char *title,
time_t base, int days_back)
{
struct tm *full_time;
char buffer[64];
struct node *node;
base += days_back * 60 * 60 * 24;
if (!title) {
full_time = localtime(&base);
strftime((char *)&buffer, (size_t)64, "%A", full_time);
node = tree_create_folder_node(NULL, buffer);
} else
node = tree_create_folder_node(NULL, title);
if (!node)
return;
node->retain_in_memory = true;
node->deleted = true;
node->editable = false;
global_history_base_node[global_history_base_node_count] = node;
global_history_base_node_time[global_history_base_node_count] = base;
global_history_base_node_count++;
}

View File

@ -19,11 +19,12 @@
#ifndef AMIGA_HISTORY_H
#define AMIGA_HISTORY_H
#include "desktop/tree.h"
#include "desktop/history_global_core.h"
#define GLOBAL_HISTORY_RECENT_URLS 16
void ami_global_history_initialise(void);
void ami_global_history_free(void);
struct tree *global_history_tree;
struct treeview_window *global_history_window;
#endif

View File

@ -1,5 +1,4 @@
/*
* Copyright 2004, 2005 Richard Wilson <info@tinct.net>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
@ -17,137 +16,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/browser.h"
#include "desktop/tree.h"
#include <proto/exec.h>
#include "content/urldb.h"
#include "amiga/hotlist.h"
#include "desktop/hotlist.h"
#include "amiga/tree.h"
void ami_gui_hotlist_visited(hlcache_handle *content, struct tree *tree,
struct node *node);
static const struct {
const char *url;
const char *msg_key;
} default_entries[] = {
{ "http://www.netsurf-browser.org/", "HotlistHomepage" },
{ "http://www.netsurf-browser.org/downloads/amiga/", "HotlistTestBuild" },
{ "http://www.netsurf-browser.org/documentation/", "HotlistDocumentation" },
{ "http://sourceforge.net/tracker/?atid=464312&group_id=51719",
"HotlistBugTracker" },
{ "http://sourceforge.net/tracker/?atid=464315&group_id=51719",
"HotlistFeatureRequest" },
{ "http://www.unsatisfactorysoftware.co.uk/",
"Unsatisfactory Software" }
};
#define ENTRIES_COUNT (sizeof(default_entries) / sizeof(default_entries[0]))
void hotlist_visited(hlcache_handle *c)
void ami_hotlist_initialise(const char *hotlist_file)
{
if ((!c) || (!content_get_url(c)) || (!hotlist))
return;
ami_gui_hotlist_visited(c, hotlist, hotlist->root);
hotlist_window = ami_tree_create(hotlist_get_tree_flags(), NULL);
if(!hotlist_window) return;
hotlist_initialise(ami_tree_get_tree(hotlist_window),
hotlist_file);
}
/**
* Informs the hotlist that some content has been visited
*
* \param content the content visited
* \param tree the tree to find the URL data from
* \param node the node to update siblings and children of
*/
void ami_gui_hotlist_visited(hlcache_handle *content, struct tree *tree,
struct node *node)
void ami_hotlist_free(const char *hotlist_file)
{
struct node_element *element;
for (; node; node = node->next) {
if (!node->folder) {
element = tree_find_element(node, TREE_ELEMENT_URL);
if ((element) && (!strcmp(element->text,
content_get_url(content)))) {
tree_update_URL_node(node, content_get_url(content), NULL);
tree_handle_node_changed(tree, node, true,
false);
}
}
if (node->child)
ami_gui_hotlist_visited(content, tree, node->child);
}
}
void ami_hotlist_init(struct tree **hotlist)
{
struct tree *hotlist_tree;
struct node *node;
int i;
const struct url_data *data;
*hotlist = AllocVec(sizeof(struct tree),MEMF_PRIVATE | MEMF_CLEAR);
hotlist_tree = *hotlist;
if (!hotlist_tree) {
warn_user("NoMemory", 0);
return;
}
hotlist_tree->root = tree_create_folder_node(NULL, "Root");
if (!hotlist_tree->root) {
warn_user("NoMemory", 0);
FreeVec(hotlist_tree);
hotlist_tree = NULL;
}
hotlist_tree->root->expanded = true;
node = tree_create_folder_node(hotlist_tree->root, "Menu");
if (!node)
node = hotlist_tree->root;
node = tree_create_folder_node(node, "NetSurf");
if (!node)
node = hotlist_tree->root;
for (i = 0; i != ENTRIES_COUNT; i++) {
data = urldb_get_url_data(default_entries[i].url);
if (!data) {
urldb_add_url(default_entries[i].url);
urldb_set_url_persistence(
default_entries[i].url,
true);
data = urldb_get_url_data(
default_entries[i].url);
}
if (data) {
tree_create_URL_node(node,
default_entries[i].url, data,
messages_get(default_entries[i].msg_key));
}
}
tree_initialise(hotlist_tree);
}
void ami_hotlist_add(struct node *node, struct hlcache_handle *c)
{
const struct url_data *data;
data = urldb_get_url_data(content_get_url(c));
if (!data)
{
urldb_add_url(content_get_url(c));
urldb_set_url_persistence(content_get_url(c),true);
data = urldb_get_url_data(content_get_url(c));
}
if (data)
{
tree_create_URL_node(node,content_get_url(c),data,content_get_title(c));
}
tree_handle_node_changed(hotlist,node,false,true);
if(hotlist->handle)
ami_recreate_listbrowser((struct treeview_window *)hotlist->handle);
hotlist_cleanup(hotlist_file);
ami_tree_destroy(hotlist_window);
hotlist_window = NULL;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -19,9 +19,10 @@
#ifndef AMIGA_HOTLIST_H
#define AMIGA_HOTLIST_H
#include "desktop/tree.h"
#include "amiga/tree.h"
void ami_hotlist_init(struct tree **hotlist);
void ami_hotlist_add(struct node *node, struct hlcache_handle *c);
void ami_hotlist_initialise(const char *hotlist_file);
void ami_hotlist_free(const char *hotlist_file);
struct tree *hotlist;
struct treeview_window *hotlist_window;
#endif

View File

@ -41,6 +41,11 @@
#include "amiga/iff_dr2d.h"
#include "amiga/clipboard.h"
#include "amiga/gui_options.h"
#include "desktop/tree_url_node.h"
#include <classes/window.h>
#include <proto/intuition.h>
#include "desktop/hotlist.h"
#include <proto/gadtools.h>
#include "amiga/print.h"
#include "amiga/download.h"
@ -61,226 +66,221 @@ const char * const versvn;
const char * const verdate;
static struct Hook aslhookfunc;
void ami_menu_scan(struct tree *tree,struct NewMenu *menu);
void ami_menu_scan_2(struct tree *tree,struct node *root,WORD *gen,ULONG *item,struct NewMenu *menu);
void ami_menu_arexx_scan(struct NewMenu *menu);
ULONG ami_menu_scan(struct tree *tree, bool count, struct gui_window_2 *gwin);
void ami_menu_scan_2(struct tree *tree, struct node *root, WORD *gen,
ULONG *item, bool count, struct gui_window_2 *gwin);
void ami_menu_arexx_scan(struct gui_window_2 *gwin);
static const ULONG ami_asl_mime_hook(struct Hook *mh,struct FileRequester *fr,struct AnchorPathOld *ap);
void ami_free_menulabs(void)
void ami_free_menulabs(struct gui_window_2 *gwin)
{
int i;
for(i=0;i<=AMI_MENU_MAX;i++)
for(i=0;i<=AMI_MENU_AREXX_MAX;i++)
{
if(menulab[i] && (menulab[i] != NM_BARLABEL)) ami_utf8_free(menulab[i]);
if(gwin->menulab[i] && (gwin->menulab[i] != NM_BARLABEL))
ami_utf8_free(gwin->menulab[i]);
gwin->menulab[i] = NULL;
gwin->menukey[i] = 0;
}
for(i=AMI_MENU_MAX+1;i<=AMI_MENU_AREXX_MAX;i++)
{
if(menulab[i] && (menulab[i] != NM_BARLABEL)) free(menulab[i]);
}
FreeVec(gwin->menutype);
FreeVec(gwin->menu);
gwin->menutype = NULL;
gwin->menu = NULL;
}
void ami_init_menulabs(void)
void ami_init_menulabs(struct gui_window_2 *gwin)
{
menulab[0] = ami_utf8_easy((char *)messages_get("Project"));
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("OpenFile"));
menulab[5] = ami_utf8_easy((char *)messages_get("SaveAsNS"));
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("PDFNS"));
menulab[10] = ami_utf8_easy((char *)messages_get("IFF"));
menulab[11] = NM_BARLABEL;
menulab[12] = ami_utf8_easy((char *)messages_get("CloseTab"));
menulab[13] = ami_utf8_easy((char *)messages_get("CloseWindow"));
menulab[14] = NM_BARLABEL;
menulab[15] = ami_utf8_easy((char *)messages_get("PrintNS"));
menulab[16] = NM_BARLABEL;
menulab[17] = ami_utf8_easy((char *)messages_get("About"));
menulab[18] = ami_utf8_easy((char *)messages_get("Quit"));
menulab[19] = ami_utf8_easy((char *)messages_get("Edit"));
menulab[20] = ami_utf8_easy((char *)messages_get("CutNS"));
menulab[21] = ami_utf8_easy((char *)messages_get("CopyNS"));
menulab[22] = ami_utf8_easy((char *)messages_get("PasteNS"));
menulab[23] = NM_BARLABEL;
menulab[24] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
menulab[25] = ami_utf8_easy((char *)messages_get("ClearNS"));
menulab[26] = ami_utf8_easy((char *)messages_get("Browser"));
menulab[27] = ami_utf8_easy((char *)messages_get("FindTextNS"));
menulab[28] = NM_BARLABEL;
menulab[29] = ami_utf8_easy((char *)messages_get("HistLocalNS"));
menulab[30] = ami_utf8_easy((char *)messages_get("HistGlobalNS"));
menulab[31] = NM_BARLABEL;
menulab[32] = ami_utf8_easy((char *)messages_get("ShowCookies"));
menulab[33] = NM_BARLABEL;
menulab[34] = ami_utf8_easy((char *)messages_get("ScaleNS"));
menulab[35] = ami_utf8_easy((char *)messages_get("ScaleDec"));
menulab[36] = ami_utf8_easy((char *)messages_get("ScaleNorm"));
menulab[37] = ami_utf8_easy((char *)messages_get("ScaleInc"));
menulab[38] = ami_utf8_easy((char *)messages_get("Redraw"));
menulab[39] = ami_utf8_easy((char *)messages_get("Hotlist"));
menulab[40] = ami_utf8_easy((char *)messages_get("HotlistAdd"));
menulab[41] = ami_utf8_easy((char *)messages_get("HotlistShowNS"));
menulab[42] = NM_BARLABEL;
int i;
menulab[AMI_MENU_HOTLIST_MAX] = ami_utf8_easy((char *)messages_get("Settings"));
menulab[AMI_MENU_HOTLIST_MAX+1] = ami_utf8_easy((char *)messages_get("SettingsEdit"));
menulab[AMI_MENU_HOTLIST_MAX+2] = NM_BARLABEL;
menulab[AMI_MENU_HOTLIST_MAX+3] = ami_utf8_easy((char *)messages_get("SnapshotWindow"));
menulab[AMI_MENU_HOTLIST_MAX+4] = ami_utf8_easy((char *)messages_get("SettingsSave"));
menulab[AMI_MENU_HOTLIST_MAX+5] = ami_utf8_easy((char *)messages_get("ARexx"));
menulab[AMI_MENU_HOTLIST_MAX+6] = ami_utf8_easy((char *)messages_get("ARexxExecute"));
menulab[AMI_MENU_HOTLIST_MAX+7] = NM_BARLABEL;
gwin->menutype = AllocVec(AMI_MENU_AREXX_MAX + 1, MEMF_PRIVATE | MEMF_CLEAR);
for(i=0;i <= AMI_MENU_AREXX_MAX;i++)
{
gwin->menutype[i] = NM_IGNORE;
gwin->menulab[i] = NULL;
}
gwin->menutype[0] = NM_TITLE;
gwin->menulab[0] = ami_utf8_easy((char *)messages_get("Project"));
gwin->menutype[1] = NM_ITEM;
gwin->menulab[1] = ami_utf8_easy((char *)messages_get("NewWindowNS"));
gwin->menukey[1] = 'N';
gwin->menutype[2] = NM_ITEM;
gwin->menulab[2] = ami_utf8_easy((char *)messages_get("NewTab"));
gwin->menukey[1] = 'T';
gwin->menutype[3] = NM_ITEM;
gwin->menulab[3] = NM_BARLABEL;
gwin->menutype[4] = NM_ITEM;
gwin->menulab[4] = ami_utf8_easy((char *)messages_get("OpenFile"));
gwin->menukey[4] = 'O';
gwin->menutype[5] = NM_ITEM;
gwin->menulab[5] = ami_utf8_easy((char *)messages_get("SaveAsNS"));
gwin->menukey[5] = 'S';
gwin->menutype[6] = NM_SUB;
gwin->menulab[6] = ami_utf8_easy((char *)messages_get("Source"));
gwin->menutype[7] = NM_SUB;
gwin->menulab[7] = ami_utf8_easy((char *)messages_get("TextNS"));
gwin->menutype[8] = NM_SUB;
gwin->menulab[8] = ami_utf8_easy((char *)messages_get("SaveCompNS"));
gwin->menutype[9] = NM_SUB;
gwin->menulab[9] = ami_utf8_easy((char *)messages_get("PDFNS"));
gwin->menutype[10] = NM_SUB;
gwin->menulab[10] = ami_utf8_easy((char *)messages_get("IFF"));
gwin->menutype[11] = NM_ITEM;
gwin->menulab[11] = NM_BARLABEL;
gwin->menutype[12] = NM_ITEM;
gwin->menulab[12] = ami_utf8_easy((char *)messages_get("CloseTab"));
gwin->menukey[12] = 'K';
gwin->menutype[13] = NM_ITEM;
gwin->menulab[13] = ami_utf8_easy((char *)messages_get("CloseWindow"));
gwin->menutype[14] = NM_ITEM;
gwin->menulab[14] = NM_BARLABEL;
gwin->menutype[15] = NM_ITEM;
gwin->menulab[15] = ami_utf8_easy((char *)messages_get("PrintNS"));
gwin->menukey[15] = 'P';
gwin->menutype[16] = NM_ITEM;
gwin->menulab[16] = NM_BARLABEL;
gwin->menutype[17] = NM_ITEM;
gwin->menulab[17] = ami_utf8_easy((char *)messages_get("About"));
gwin->menukey[17] = '?';
gwin->menutype[18] = NM_ITEM;
gwin->menulab[18] = ami_utf8_easy((char *)messages_get("Quit"));
gwin->menukey[18] = 'Q';
gwin->menutype[19] = NM_TITLE;
gwin->menulab[19] = ami_utf8_easy((char *)messages_get("Edit"));
gwin->menutype[20] = NM_ITEM;
gwin->menulab[20] = ami_utf8_easy((char *)messages_get("CutNS"));
gwin->menukey[20] = 'X';
gwin->menutype[21] = NM_ITEM;
gwin->menulab[21] = ami_utf8_easy((char *)messages_get("CopyNS"));
gwin->menukey[21] = 'C';
gwin->menutype[22] = NM_ITEM;
gwin->menulab[22] = ami_utf8_easy((char *)messages_get("PasteNS"));
gwin->menukey[22] = 'V';
gwin->menutype[23] = NM_ITEM;
gwin->menulab[23] = NM_BARLABEL;
gwin->menutype[24] = NM_ITEM;
gwin->menulab[24] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
gwin->menukey[24] = 'A';
gwin->menutype[25] = NM_ITEM;
gwin->menulab[25] = ami_utf8_easy((char *)messages_get("ClearNS"));
gwin->menukey[25] = 'Z';
gwin->menutype[26] = NM_TITLE;
gwin->menulab[26] = ami_utf8_easy((char *)messages_get("Browser"));
gwin->menutype[27] = NM_ITEM;
gwin->menulab[27] = ami_utf8_easy((char *)messages_get("FindTextNS"));
gwin->menukey[27] = 'F';
gwin->menutype[28] = NM_ITEM;
gwin->menulab[28] = NM_BARLABEL;
gwin->menutype[29] = NM_ITEM;
gwin->menulab[29] = ami_utf8_easy((char *)messages_get("HistLocalNS"));
gwin->menutype[30] = NM_ITEM;
gwin->menulab[30] = ami_utf8_easy((char *)messages_get("HistGlobalNS"));
gwin->menutype[31] = NM_ITEM;
gwin->menulab[31] = NM_BARLABEL;
gwin->menutype[32] = NM_ITEM;
gwin->menulab[32] = ami_utf8_easy((char *)messages_get("ShowCookies"));
gwin->menutype[33] = NM_ITEM;
gwin->menulab[33] = NM_BARLABEL;
gwin->menutype[34] = NM_ITEM;
gwin->menulab[34] = ami_utf8_easy((char *)messages_get("ScaleNS"));
gwin->menutype[35] = NM_SUB;
gwin->menulab[35] = ami_utf8_easy((char *)messages_get("ScaleDec"));
gwin->menukey[35] = '-';
gwin->menutype[36] = NM_SUB;
gwin->menulab[36] = ami_utf8_easy((char *)messages_get("ScaleNorm"));
gwin->menukey[36] = '=';
gwin->menutype[37] = NM_SUB;
gwin->menulab[37] = ami_utf8_easy((char *)messages_get("ScaleInc"));
gwin->menukey[37] = '+';
gwin->menutype[38] = NM_ITEM;
gwin->menulab[38] = ami_utf8_easy((char *)messages_get("Redraw"));
gwin->menutype[39] = NM_TITLE;
gwin->menulab[39] = ami_utf8_easy((char *)messages_get("Hotlist"));
gwin->menukey[39] = 'H';
gwin->menutype[40] = NM_ITEM;
gwin->menulab[40] = ami_utf8_easy((char *)messages_get("HotlistAdd"));
gwin->menutype[41] = NM_ITEM;
gwin->menulab[41] = ami_utf8_easy((char *)messages_get("HotlistShowNS"));
gwin->menutype[42] = NM_ITEM;
gwin->menulab[42] = NM_BARLABEL;
gwin->menutype[AMI_MENU_HOTLIST_MAX + 1] = NM_TITLE;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 1] = ami_utf8_easy((char *)messages_get("Settings"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 2] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 2] = ami_utf8_easy((char *)messages_get("SettingsEdit"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 3] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 3] = NM_BARLABEL;
gwin->menutype[AMI_MENU_HOTLIST_MAX + 4] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 4] = ami_utf8_easy((char *)messages_get("SnapshotWindow"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 5] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 5] = ami_utf8_easy((char *)messages_get("SettingsSave"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 6] = NM_TITLE;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 6] = ami_utf8_easy((char *)messages_get("ARexx"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 7] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 7] = ami_utf8_easy((char *)messages_get("ARexxExecute"));
gwin->menutype[AMI_MENU_HOTLIST_MAX + 8] = NM_ITEM;
gwin->menulab[AMI_MENU_HOTLIST_MAX + 8] = NM_BARLABEL;
gwin->menutype[AMI_MENU_AREXX_MAX] = NM_END;
}
struct NewMenu *ami_create_menu(ULONG type)
void ami_menu_refresh(struct gui_window_2 *gwin)
{
SetAttrs(gwin->objects[OID_MAIN],
WINDOW_NewMenu, NULL,
TAG_DONE);
ami_free_menulabs(gwin);
ami_create_menu(BROWSER_WINDOW_NORMAL, gwin);
SetAttrs(gwin->objects[OID_MAIN],
WINDOW_NewMenu, gwin->menu,
TAG_DONE);
schedule(6000,(void *)ami_menu_refresh,gwin);
}
struct NewMenu *ami_create_menu(ULONG type, struct gui_window_2 *gwin)
{
int i;
ULONG menuflags = 0;
STATIC struct NewMenu menu[] = {
{NM_TITLE,0,0,0,0,0,}, // project
{ 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
{ NM_SUB,0,0,0,0,0,}, // save as complete
{ NM_SUB,0,0,0,0,0,}, // save as pdf
{ NM_SUB,0,0,0,0,0,}, // save as iff
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ 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,"P",0,0,0,}, // print
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,"?",0,0,0,}, // about
{ NM_ITEM,0,"Q",0,0,0,}, // quit
{NM_TITLE,0,0,0,0,0,}, // edit
{ NM_ITEM,0,"X",0,0,0,}, // cut
{ NM_ITEM,0,"C",0,0,0,}, // copy
{ NM_ITEM,0,"V",0,0,0,}, // paste
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,"A",0,0,0,}, // select all
{ NM_ITEM,0,"Z",0,0,0,}, // clear selection
{NM_TITLE,0,0,0,0,0,}, // browser
{ NM_ITEM,0,"F",0,0,0,}, // find in page
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,0,0,0,0,}, // local history
{ NM_ITEM,0,0,0,0,0,}, // global history
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,0,0,0,0,}, // cookies
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,0,0,0,0,}, // scale
{ NM_SUB,0,"-",0,0,0,}, // decrease
{ NM_SUB,0,"=",0,0,0,}, // normal
{ NM_SUB,0,"+",0,0,0,}, // increase
{ NM_ITEM,0,0,0,0,0,}, // redraw
{NM_TITLE,0,0,0,0,0,}, // hotlist
{ NM_ITEM,0,0,0,0,0,}, // add to hotlist
{ NM_ITEM,0,"H",0,0,0,}, // show hotlist (treeview)
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** hotlist entry **
{NM_TITLE,0,0,0,0,0,}, // settings
{ NM_ITEM,0,0,0,0,0,}, // edit prefs
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_ITEM,0,0,0,0,0,}, // snapshot window
{ NM_ITEM,0,0,0,0,0,}, // save settings
{NM_TITLE,0,0,0,0,0,}, // arexx
{ NM_ITEM,0,0,0,0,0,}, // execute arexx
{ NM_ITEM,NM_BARLABEL,0,0,0,0,},
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_IGNORE,0,0,0,0,0,}, // ** arexx entry **
{ NM_END,0,0,0,0,0,},
};
ami_init_menulabs(gwin);
gwin->menu = AllocVec(sizeof(struct NewMenu) * (AMI_MENU_AREXX_MAX + 1), MEMF_CLEAR);
if(type != BROWSER_WINDOW_NORMAL)
{
menuflags = NM_ITEMDISABLED;
}
for(i=0;i<=AMI_MENU_MAX;i++)
for(i=0;i<=AMI_MENU_AREXX_MAX;i++)
{
menu[i].nm_Label = menulab[i];
gwin->menu[i].nm_Type = gwin->menutype[i];
gwin->menu[i].nm_Label = gwin->menulab[i];
if(gwin->menukey[i]) gwin->menu[i].nm_CommKey = &gwin->menukey[i];
gwin->menu[i].nm_Flags = 0;
}
menu[1].nm_Flags = menuflags;
menu[2].nm_Flags = menuflags;
menu[12].nm_Flags = menuflags;
menu[13].nm_Flags = menuflags;
gwin->menu[1].nm_Flags = menuflags;
gwin->menu[2].nm_Flags = menuflags;
gwin->menu[12].nm_Flags = menuflags;
gwin->menu[13].nm_Flags = menuflags;
#ifndef WITH_PDF_EXPORT
menu[9].nm_Flags = NM_ITEMDISABLED;
gwin->menu[9].nm_Flags = NM_ITEMDISABLED;
#endif
ami_menu_scan(ami_tree_get_tree(hotlist_window), false, gwin);
ami_menu_arexx_scan(gwin);
if(!menualreadyinit)
{
ami_menu_scan(hotlist,menu);
ami_menu_arexx_scan(&menu);
aslhookfunc.h_Entry = (void *)&ami_asl_mime_hook;
aslhookfunc.h_SubEntry = NULL;
aslhookfunc.h_Data = NULL;
@ -288,10 +288,16 @@ struct NewMenu *ami_create_menu(ULONG type)
menualreadyinit = TRUE;
}
return(menu);
/* Set up scheduler to refresh the hotlist menu
Disabled as it causes everything to slow down to a halt after
several iterations
schedule(6000,(void *)ami_menu_refresh,gwin);
*/
return(gwin->menu);
}
void ami_menu_arexx_scan(struct NewMenu *menu)
void ami_menu_arexx_scan(struct gui_window_2 *gwin)
{
int item = AMI_MENU_AREXX;
BPTR lock = 0;
@ -323,23 +329,20 @@ void ami_menu_arexx_scan(struct NewMenu *menu)
for(ead = (struct ExAllData *)buffer; ead; ead = ead->ed_Next)
{
if(item >= AMI_MENU_AREXX_MAX) continue;
if(!strcasecmp(ead->ed_Name, option_arexx_startup)) continue;
if(!strcasecmp(ead->ed_Name, option_arexx_shutdown)) continue;
if(EAD_IS_FILE(ead))
{
menu[item].nm_Type = NM_ITEM;
gwin->menu[item].nm_Type = NM_ITEM;
if(ead->ed_Comment[0] != '\0')
{
menulab[item] = (char *)strdup(ead->ed_Comment);
gwin->menulab[item] = (char *)strdup(ead->ed_Comment);
}
else
{
menulab[item] = (char *)strdup(ead->ed_Name);
gwin->menulab[item] = (char *)strdup(ead->ed_Name);
}
menu[item].nm_Label = menulab[item];
menu[item].nm_UserData = (char *)strdup(ead->ed_Name);
gwin->menu[item].nm_Label = gwin->menulab[item];
gwin->menu[item].nm_UserData = (char *)strdup(ead->ed_Name);
item++;
}
@ -351,31 +354,37 @@ void ami_menu_arexx_scan(struct NewMenu *menu)
}
UnLock(lock);
}
gwin->menu[item].nm_Type = NM_END;
gwin->menu[item].nm_Label = NULL;
}
void ami_menu_scan(struct tree *tree,struct NewMenu *menu)
ULONG ami_menu_scan(struct tree *tree, bool count, struct gui_window_2 *gwin)
{
struct node *root = tree->root->child;
struct node_element *element=NULL;
struct node *root = tree_node_get_child(tree_get_root(tree));
struct node *node;
struct node_element *element;
static WORD gen = 0;
static ULONG item;
item = AMI_MENU_HOTLIST;
for (node = root; node; node = node->next)
for (node = root; node; node = tree_node_get_next(node))
{
element = tree_find_element(node, TREE_ELEMENT_NAME);
if(!element) element = tree_find_element(node, TREE_ELEMENT_TITLE);
if(element && (strcmp(element->text,"Menu")==0))
element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
if(!element) element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
if(element && (strcmp(tree_node_element_get_text(element),"Menu")==0))
{
// found menu
ami_menu_scan_2(tree,node->child,&gen,&item,menu);
ami_menu_scan_2(tree,tree_node_get_child(node),&gen,&item,count,gwin);
}
}
return(item - AMI_MENU_HOTLIST);
}
void ami_menu_scan_2(struct tree *tree,struct node *root,WORD *gen,ULONG *item,struct NewMenu *menu)
void ami_menu_scan_2(struct tree *tree,struct node *root,WORD *gen,
ULONG *item, bool count, struct gui_window_2 *gwin)
{
struct node *tempnode;
struct node_element *element=NULL;
@ -383,38 +392,39 @@ void ami_menu_scan_2(struct tree *tree,struct node *root,WORD *gen,ULONG *item,s
*gen = *gen + 1;
for (node = root; node; node = node->next)
for (node = root; node; node = tree_node_get_next(node))
{
element = tree_find_element(node, TREE_ELEMENT_TITLE);
if((*gen > 0) && (*gen < 3))
{
if(*item >= AMI_MENU_HOTLIST_MAX) return;
// if(*item >= AMI_MENU_HOTLIST_MAX) return;
if(*gen == 1) menu[*item].nm_Type = NM_ITEM;
if(*gen == 2) menu[*item].nm_Type = NM_SUB;
if(strcmp(element->text,"--"))
if(!count)
{
menulab[*item] = ami_utf8_easy((char *)element->text);
}
else
{
menulab[*item] = NM_BARLABEL;
}
if(*gen == 1) gwin->menu[*item].nm_Type = NM_ITEM;
if(*gen == 2) gwin->menu[*item].nm_Type = NM_SUB;
menu[*item].nm_Label = menulab[*item];
if(strcmp(tree_url_node_get_title(node),"--"))
{
gwin->menulab[*item] = ami_utf8_easy((char *)tree_url_node_get_title(node));
}
else
{
gwin->menulab[*item] = NM_BARLABEL;
}
element = tree_find_element(node, TREE_ELEMENT_URL);
if(element && element->text) menu[*item].nm_UserData = (void *)element->text;
if(node->folder && (!node->child)) menu[*item].nm_Flags = NM_ITEMDISABLED;
gwin->menu[*item].nm_Label = gwin->menulab[*item];
gwin->menu[*item].nm_UserData = (void *)tree_url_node_get_url(node);
if(tree_node_is_folder(node) && (!tree_node_get_child(node)))
gwin->menu[*item].nm_Flags = NM_ITEMDISABLED;
}
*item = *item + 1;
}
if (node->child)
if (tree_node_get_child(node))
{
ami_menu_scan_2(tree,node->child,gen,item,menu);
ami_menu_scan_2(tree,tree_node_get_child(node),gen,item,count,gwin);
}
}
@ -698,11 +708,11 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item)
break;
case 3: // global history
ami_open_tree(global_history_tree,AMI_TREE_HISTORY);
ami_tree_open(global_history_window,AMI_TREE_HISTORY);
break;
case 5: // cookies tree
ami_open_tree(cookies_tree,AMI_TREE_COOKIES);
ami_tree_open(cookies_window,AMI_TREE_COOKIES);
break;
case 7: // size
@ -736,12 +746,18 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item)
switch(itemnum)
{
case 0: // add
ami_hotlist_add(hotlist->root,gwin->bw->current_content);
options_save_tree(hotlist,option_hotlist_file,messages_get("TreeHotlist"));
if (bw == NULL ||
bw->current_content
== NULL ||
content_get_url(bw->current_content)
== NULL)
break;
hotlist_add_page(content_get_url(gwin->bw->
current_content));
break;
case 1: // show
ami_open_tree(hotlist,AMI_TREE_HOTLIST);
ami_tree_open(hotlist_window, AMI_TREE_HOTLIST);
break;
default: // bookmarks

View File

@ -19,12 +19,14 @@
#ifndef AMIGA_MENU_H
#define AMIGA_MENU_H
#include <exec/types.h>
#include "amiga/gui.h"
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include "content/hlcache.h"
/* Number of hotlist items, menu structure needs to be changed in ami_create_menu()
* if this value is changed. */
#define AMI_HOTLIST_ITEMS 40
#define AMI_HOTLIST_ITEMS 60
//gwin->hotlist_items
/* Maximum number of menu items - first value is number of static items
* (ie. everything not intially defined as NM_IGNORE) */
@ -61,11 +63,12 @@
#define AMI_MENU_CLEAR FULLMENUNUM(1,5,0)
#define AMI_MENU_FIND FULLMENUNUM(2,0,0)
char *menulab[AMI_MENU_AREXX_MAX+1];
struct gui_window;
struct gui_window_2;
struct NewMenu *ami_create_menu(ULONG type);
void ami_init_menulabs(void);
void ami_free_menulabs(void);
void ami_free_menulabs(struct gui_window_2 *gwin);
struct NewMenu *ami_create_menu(ULONG type, struct gui_window_2 *gwin);
void ami_menu_refresh(struct gui_window_2 *gwin);
void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item);
void ami_menu_update_disabled(struct gui_window *g, hlcache_handle *c);
#endif

View File

@ -48,14 +48,24 @@ struct nsObject *AddObject(struct MinList *objlist,ULONG otype)
return(dtzo);
}
void DelObject(struct nsObject *dtzo)
void DelObjectInternal(struct nsObject *dtzo, BOOL free_obj)
{
Remove((struct Node *)dtzo);
if(dtzo->objstruct) FreeVec(dtzo->objstruct);
if(dtzo->objstruct && free_obj) FreeVec(dtzo->objstruct);
FreeVec(dtzo);
dtzo = NULL;
}
void DelObject(struct nsObject *dtzo)
{
DelObjectInternal(dtzo, TRUE);
}
void DelObjectNoFree(struct nsObject *dtzo)
{
DelObjectInternal(dtzo, FALSE);
}
void FreeObjList(struct MinList *objlist)
{
struct nsObject *node;

View File

@ -48,6 +48,7 @@ struct nsObject
struct MinList *NewObjList(void);
struct nsObject *AddObject(struct MinList *objlist,ULONG otype);
void DelObject(struct nsObject *dtzo);
void DelObjectNoFree(struct nsObject *dtzo);
void FreeObjList(struct MinList *objlist);
#endif

View File

@ -34,7 +34,6 @@ extern bool option_truecolour_mouse_pointers;
extern bool option_use_os_pointers;
extern bool option_new_tab_active;
extern bool option_kiosk_mode;
extern char *option_recent_file;
extern char *option_search_engines_file;
extern char *option_search_ico_file;
extern char *option_arexx_dir;
@ -68,7 +67,6 @@ bool option_truecolour_mouse_pointers = false; \
bool option_use_os_pointers = true; \
bool option_new_tab_active = false; \
bool option_kiosk_mode = false; \
char *option_recent_file = 0; \
char *option_search_engines_file = 0; \
char *option_search_ico_file = 0; \
char *option_arexx_dir = 0; \
@ -102,7 +100,6 @@ bool option_drag_save_icons = true; \
{ "os_mouse_pointers", OPTION_BOOL, &option_use_os_pointers}, \
{ "new_tab_is_active", OPTION_BOOL, &option_new_tab_active}, \
{ "kiosk_mode", OPTION_BOOL, &option_kiosk_mode}, \
{ "recent_file", OPTION_STRING, &option_recent_file }, \
{ "search_engines_file", OPTION_STRING, &option_search_engines_file }, \
{ "search_ico_file", OPTION_STRING, &option_search_ico_file }, \
{ "arexx_dir", OPTION_STRING, &option_arexx_dir }, \

View File

@ -91,7 +91,7 @@ void ami_cairo_set_colour(cairo_t *cr,colour c)
void ami_cairo_set_solid(cairo_t *cr)
{
double dashes = 0;
cairo_set_dash(glob->cr, &dashes, 0, 0);
}
@ -240,7 +240,7 @@ bool ami_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style)
glob->rp.LinePtrn = PATT_DASH;
break;
}
SetRPAttrs(&glob->rp,
RPTAG_APenColor,
p96EncodeColor(RGBFB_A8B8G8R8, style->stroke_colour),
@ -272,7 +272,7 @@ bool ami_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style)
break;
}
if (style->stroke_width == 0)
if (style->stroke_width == 0)
cairo_set_line_width(glob->cr, 1);
else
cairo_set_line_width(glob->cr, style->stroke_width);
@ -337,13 +337,17 @@ bool ami_line(int x0, int y0, int x1, int y1, const plot_style_t *style)
break;
}
if (style->stroke_width == 0)
if (style->stroke_width == 0)
cairo_set_line_width(glob->cr, 1);
else
cairo_set_line_width(glob->cr, style->stroke_width);
cairo_move_to(glob->cr, x0 + 0.5, y0 + 0.5);
cairo_line_to(glob->cr, x1 + 0.5, y1 + 0.5);
/* core expects horizontal and vertical lines to be on pixels, not
* between pixels */
cairo_move_to(current_cr, (x0 == x1) ? x0 + 0.5 : x0,
(y0 == y1) ? y0 + 0.5 : y0);
cairo_line_to(current_cr, (x0 == x1) ? x1 + 0.5 : x1,
(y0 == y1) ? y1 + 0.5 : y1);
cairo_stroke(glob->cr);
#endif
return true;
@ -426,7 +430,7 @@ bool ami_clip(int x0, int y0, int x1, int y1)
return true;
}
bool ami_text(int x, int y, const char *text, size_t length,
bool ami_text(int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle)
{
#ifdef AMI_PLOTTER_DEBUG
@ -459,7 +463,7 @@ bool ami_disc(int x, int y, int radius, const plot_style_t *style)
p96EncodeColor(RGBFB_A8B8G8R8, style->stroke_colour),
TAG_DONE);
DrawEllipse(&glob->rp,x,y,radius,radius);
DrawEllipse(&glob->rp,x,y,radius,radius);
}
#else
if (style->fill_type != PLOT_OP_TYPE_NONE) {

View File

@ -24,12 +24,8 @@ theme_closetab_g:*TBImages:list_cancel
theme_addtab:*TBImages:list_add
theme_addtab_s:*TBImages:list_add
theme_addtab_g:*TBImages:list_add
theme_list_folder_closed:*TBImages:list_folderfold
theme_list_folder_open:*TBImages:list_folderunfold
theme_list_bookmark:*TBImages:list_bookmark
theme_list_cookie:*TBImages:list_abstract
theme_list_history:*TBImages:list_archive
theme_list_sslcert:*TBImages:list_crypt
theme_list_folder:*TBImages:list_drawer
theme_list_content:*TBImages:list_abstract
theme_throbber:Throbber
theme_throbber_frames:13
theme_throbber_delay:100

View File

@ -37,12 +37,8 @@ theme_closetab_g:closetab_g.png
theme_addtab:
theme_addtab_s:
theme_addtab_g:
theme_list_folder_closed:
theme_list_folder_open:
theme_list_bookmark:
theme_list_cookie:
theme_list_history:
theme_list_sslcert:
theme_list_folder:directory.png
theme_list_content:content.png
theme_throbber:Throbber
theme_throbber_frames:9
theme_throbber_delay:100

View File

@ -0,0 +1 @@
../../../../!NetSurf/Resources/Icons/content.png

View File

@ -0,0 +1 @@
../../../../!NetSurf/Resources/Icons/directory.png

View File

@ -16,224 +16,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include "utils/errors.h"
#include "utils/utils.h"
#include "utils/messages.h"
#include "content/urldb.h"
#include "content/fetch.h"
#include "desktop/tree.h"
#include "amiga/tree.h"
#include "amiga/gui.h"
struct session_data {
struct session_cert *certs;
unsigned long num;
nserror (*cb)(bool proceed, void *pw);
void *cbpw;
char *url;
struct tree *tree;
};
struct session_cert {
char version[16], valid_from[32], valid_to[32], type[8], serial[32];
char *issuer_t;
char *subject_t;
uintptr_t issuer;
uintptr_t subject;
};
void ami_gui_cert_close(struct session_data *data);
bool ami_gui_cert_apply(struct session_data *session);
#include "amiga/sslcert.h"
void gui_cert_verify(const char *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
const struct ssl_cert_info *from;
struct session_cert *to;
struct session_data *data;
struct tree *tree;
struct node *node;
long i;
STRPTR yesorno,reqcontents;
int res = 0;
struct treeview_window *twin;
struct sslcert_session_data *data;
struct treeview_window *ssl_window;
assert(certs);
data = sslcert_create_session_data(num, url, cb, cbpw);
/* copy the certificate information */
data = calloc(1, sizeof(struct session_data));
if (!data) {
warn_user("NoMemory", 0);
return;
}
data->url = strdup(url);
if (!data->url) {
free(data);
warn_user("NoMemory", 0);
return;
}
data->cb = cb;
data->cbpw = cbpw;
data->num = num;
data->certs = calloc(num, sizeof(struct session_cert));
if (!data->certs) {
free(data->url);
free(data);
warn_user("NoMemory", 0);
return;
}
for (i = 0; i < (long)num; i++) {
to = &data->certs[i];
from = &certs[i];
to->subject_t = strdup(from->subject);
to->issuer_t = strdup(from->issuer);
if ((!to->subject_t) || (!to->issuer_t)) {
for (; i >= 0; i--) {
to = &data->certs[i];
free(to->subject_t);
free(to->issuer_t);
}
free(data->certs);
free(data->url);
free(data);
warn_user("NoMemory", 0);
return;
}
snprintf(to->version, sizeof data->certs->version, "%ld",
from->version);
snprintf(to->valid_from, sizeof data->certs->valid_from, "%s",
from->not_before);
snprintf(to->type, sizeof data->certs->type, "%d",
from->cert_type);
snprintf(to->valid_to, sizeof data->certs->valid_to, "%s",
from->not_after);
snprintf(to->serial, sizeof data->certs->serial, "%ld",
from->serial);
}
ssl_window = ami_tree_create(sslcert_get_tree_flags(), data);
if(!ssl_window) return;
tree = calloc(sizeof(struct tree), 1);
if (!tree) {
//ro_gui_cert_close(ssl_w);
warn_user("NoMemory", 0);
return;
}
tree->root = tree_create_folder_node(NULL, "Root");
if (!tree->root) {
// ro_gui_cert_close(ssl_w);
warn_user("NoMemory", 0);
free(tree);
tree = NULL;
return;
}
tree->root->expanded = true;
tree->handle = 0;
tree->movable = false;
tree->no_drag = true;
tree->no_vscroll = true;
tree->no_furniture = true;
tree->single_selection = true;
data->tree = tree;
/* put the SSL names in the tree */
for (i = 0; i < (long)num; i++) {
node = tree_create_leaf_node(tree->root, certs[i].subject);
if (node) {
node->data.data = TREE_ELEMENT_SSL;
tree_set_node_sprite(node, "small_xxx", "small_xxx");
}
}
tree_initialise(tree);
ami_open_tree(tree,AMI_TREE_SSLCERT);
twin = (struct treeview_window *)data->tree->handle;
if(yesorno = ASPrintf("%s|%s",messages_get("Accept"),messages_get("Reject")))
{
if(reqcontents = ASPrintf("%s\n\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s",
messages_get("SSLError"),
messages_get("Subject"),
to->subject_t,
messages_get("Issuer"),
to->issuer_t,
messages_get("Version"),
to->version,
messages_get("ValidFrom"),
to->valid_from,
messages_get("ValidTo"),
to->valid_to))
{
res = TimedDosRequesterTags(TDR_ImageType,TDRIMAGE_QUESTION,
TDR_Window,twin->win,
TDR_TitleString,messages_get("NetSurf"),
TDR_GadgetString,yesorno,
TDR_FormatString,reqcontents,
TAG_DONE);
FreeVec(reqcontents);
}
FreeVec(yesorno);
}
if(res == 1)
{
ami_gui_cert_apply(data);
}
ami_gui_cert_close(data);
sslcert_load_tree(ami_tree_get_tree(ssl_window), certs, data);
ami_tree_open(ssl_window, AMI_TREE_SSLCERT);
}
void ami_gui_cert_close(struct session_data *data)
void ami_ssl_free(struct treeview_window *twin)
{
unsigned long i;
if(data->tree->handle)
{
ami_tree_close((struct treeview_window *)data->tree->handle);
win_destroyed = true;
}
assert(data);
/*
for (i = 0; i < data->num; i++) {
if (data->certs[i].subject)
textarea_destroy(data->certs[i].subject);
if (data->certs[i].issuer)
textarea_destroy(data->certs[i].issuer);
}
*/
/* Send failure if callback exists */
if (data->cb != NULL)
data->cb(false, data->cbpw);
if (data->tree) {
tree_delete_node(data->tree, data->tree->root, false);
free(data->tree);
}
free(data->certs);
free(data->url);
free(data);
}
bool ami_gui_cert_apply(struct session_data *session)
{
assert(session);
urldb_set_cert_permissions(session->url, true);
session->cb(true, session->cbpw);
/* Invalidate callback */
session->cb = NULL;
session->cbpw = NULL;
return true;
ami_tree_destroy(twin);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
* Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/browser.h"
#include "content/hlcache.h"
#ifndef AMIGA_SSLCERT_H
#define AMIGA_SSLCERT_H
#include "desktop/sslcert.h"
void hotlist_visited(hlcache_handle *content)
{
}
void ami_ssl_free(struct treeview_window *twin);
#endif

View File

@ -121,7 +121,7 @@ void ami_theme_throbber_setup(void)
char throbberfile[1024];
Object *dto;
ami_get_theme_filename(throbberfile,"theme_throbber");
ami_get_theme_filename(throbberfile,"theme_throbber",false);
throbber_frames=atoi(messages_get("theme_throbber_frames"));
throbber_update_interval = atoi(messages_get("theme_throbber_delay"));
if(throbber_update_interval == 0) throbber_update_interval = 100;
@ -170,15 +170,20 @@ void ami_theme_throbber_free(void)
p96FreeBitMap(throbber);
}
void ami_get_theme_filename(char *filename, char *themestring)
void ami_get_theme_filename(char *filename, char *themestring, bool protocol)
{
if(protocol)
strcpy(filename,"file:///");
else
strcpy(filename,"");
if(messages_get(themestring)[0] == '*')
{
strncpy(filename, messages_get(themestring) + 1, 100);
strncat(filename,messages_get(themestring)+1,100);
}
else
{
strcpy(filename, option_theme);
strcat(filename, option_theme);
AddPart(filename, messages_get(themestring), 100);
}
}
@ -273,7 +278,7 @@ void ami_init_mouse_pointers(void)
if(option_truecolour_mouse_pointers)
{
ami_get_theme_filename(&ptrfname,ptrs32[i]);
ami_get_theme_filename(&ptrfname,ptrs32[i], false);
if(dobj = GetIconTags(ptrfname,ICONGETA_UseFriendBitMap,TRUE,TAG_DONE))
{
if(IconControl(dobj, ICONCTRLA_GetImageDataFormat, &format, TAG_DONE))
@ -325,7 +330,7 @@ void ami_init_mouse_pointers(void)
if(!mouseptrobj[i])
{
ami_get_theme_filename(ptrfname,ptrs[i]);
ami_get_theme_filename(ptrfname,ptrs[i], false);
if(ptrfile = Open(ptrfname,MODE_OLDFILE))
{
int mx,my;

View File

@ -27,7 +27,7 @@
ULONG throbber_width, throbber_height;
void ami_theme_init(void);
void ami_get_theme_filename(char *filename, char *themestring);
void ami_get_theme_filename(char *filename, char *themestring, bool protocol);
void ami_theme_throbber_setup(void);
void ami_theme_throbber_free(void);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
* Copyright 2008, 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -22,15 +22,10 @@
#include <exec/types.h>
#include <intuition/classusr.h>
#include "amiga/gui.h"
#include "desktop/tree.h"
#include "desktop/sslcert.h"
struct treeview_window {
struct nsObject *node;
struct Window *win;
Object *objects[OID_LAST];
struct Gadget *gadgets[GID_LAST];
struct tree *tree;
struct List *listbrowser_list;
};
struct treeview_window;
enum
{
@ -40,15 +35,15 @@ enum
AMI_TREE_SSLCERT
};
enum
{
AMI_MOVE_UP,
AMI_MOVE_DOWN,
AMI_MOVE_OUT
};
struct treeview_window *ami_tree_create(uint8 flags,
struct sslcert_session_data *ssl_data);
void ami_tree_destroy(struct treeview_window *twin);
struct tree *ami_tree_get_tree(struct treeview_window *twin);
void ami_open_tree(struct tree *tree,int type);
void ami_tree_open(struct treeview_window *twin,int type);
void ami_tree_close(struct treeview_window *twin);
BOOL ami_tree_event(struct treeview_window *twin);
void ami_recreate_listbrowser(struct treeview_window *twin);
extern const struct treeview_table ami_tree_callbacks;
#endif

View File

@ -312,6 +312,16 @@ void bitmap_set_suspendable(void *vbitmap, void *private_word,
struct bitmap *bitmap = (struct bitmap *)vbitmap;
}
int bitmap_get_width(void *vbitmap){
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Width() + 1;
}
int bitmap_get_height(void *vbitmap){
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Height() + 1;
}
static BBitmap *
nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y)
{

View File

@ -74,7 +74,6 @@ extern "C" {
#include "beos/beos_window.h"
#include "beos/options.h"
#include "beos/beos_throbber.h"
#include "beos/beos_history.h"
#include "beos/beos_filetype.h"
//#include "beos/beos_download.h"
#include "beos/beos_schedule.h"
@ -641,7 +640,6 @@ void gui_init(int argc, char** argv)
urldb_load(option_url_file);
urldb_load_cookies(option_cookie_file);
nsbeos_history_init();
//nsbeos_download_initialise();
if (!replicated)
@ -1059,11 +1057,6 @@ void die(const char * const error)
exit(EXIT_FAILURE);
}
void hotlist_visited(hlcache_handle *content)
{
}
void gui_cert_verify(const char *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)

View File

@ -1,183 +0,0 @@
/*
* Copyright 2008 François Revol <mmu_man@users.sourceforge.net>
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define __STDBOOL_H__ 1
extern "C" {
#include "utils/log.h"
#include "content/urldb.h"
}
#include "beos/beos_history.h"
#include "beos/beos_gui.h"
#include "beos/beos_window.h"
#include <View.h>
#include <Window.h>
enum
{
COL_TITLE = 0,
COL_ADDRESS,
COL_LASTVISIT,
COL_TOTALVISITS,
COL_THUMBNAIL,
COL_NCOLS
};
BWindow *wndHistory;
#warning XXX
#if 0 /* GTK */
static GtkTreeView *treeview;
static GtkTreeStore *history_tree;
static GtkTreeSelection *selection;
static bool nsgtk_history_add_internal(const char *, const struct url_data *);
static void nsgtk_history_selection_changed(GtkTreeSelection *, gpointer);
#endif
void nsbeos_history_init(void)
{
#warning XXX
#if 0 /* GTK */
GtkCellRenderer *renderer;
wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeWindows,
"wndHistory"));
treeview = GTK_TREE_VIEW(glade_xml_get_widget(gladeWindows,
"treeHistory"));
history_tree = gtk_tree_store_new(COL_NCOLS,
G_TYPE_STRING, /* title */
G_TYPE_STRING, /* address */
G_TYPE_STRING, /* last visit */
G_TYPE_INT, /* nr. visits */
GDK_TYPE_PIXBUF); /* thumbnail */
selection = gtk_tree_view_get_selection(treeview);
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
g_signal_connect(G_OBJECT(selection), "changed",
G_CALLBACK(nsgtk_history_selection_changed), NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(treeview, -1, "Title",
renderer,
"text",
COL_TITLE,
NULL);
gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(history_tree));
#endif
nsbeos_history_update();
}
void nsbeos_history_update(void)
{
#warning XXX
#if 0 /* GTK */
gtk_tree_store_clear(history_tree);
urldb_iterate_entries(nsgtk_history_add_internal);
#endif
}
bool nsbeos_history_add_internal(const char *url, const struct url_data *data)
{
#warning XXX
#if 0 /* GTK */
GtkTreeIter iter;
if (data->visits > 0)
{
gtk_tree_store_append(history_tree, &iter, NULL);
gtk_tree_store_set(history_tree, &iter,
COL_TITLE, data->title,
COL_ADDRESS, url,
COL_LASTVISIT, "Unknown",
COL_TOTALVISITS, data->visits,
-1);
}
#endif
return true;
}
#warning XXX
#if 0 /* GTK */
void nsgtk_history_selection_changed(GtkTreeSelection *treesel, gpointer g)
{
GtkTreeIter iter;
GtkTreeModel *model = GTK_TREE_MODEL(history_tree);
if (gtk_tree_selection_get_selected(treesel, &model, &iter))
{
gchar *b;
gint i;
char buf[20];
gtk_tree_model_get(model, &iter, COL_ADDRESS, &b, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
"labelHistoryAddress")), b);
gtk_tree_model_get(model, &iter, COL_LASTVISIT, &b, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
"labelHistoryLastVisit")), b);
gtk_tree_model_get(model, &iter, COL_TOTALVISITS,
&i, -1);
snprintf(buf, 20, "%d", i);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows,
"labelHistoryVisits")), buf);
}
else
{
}
}
void nsgtk_history_row_activated(GtkTreeView *tv, GtkTreePath *path,
GtkTreeViewColumn *column, gpointer g)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model(tv);
if (gtk_tree_model_get_iter(model, &iter, path))
{
gchar *b;
gtk_tree_model_get(model, &iter, COL_ADDRESS, &b, -1);
browser_window_create((const char *)b, NULL, NULL, true);
}
}
#endif
void global_history_add(const char *url)
{
const struct url_data *data;
data = urldb_get_url_data(url);
if (!data)
return;
nsbeos_history_add_internal(url, data);
}

View File

@ -63,7 +63,6 @@ extern "C" {
#include "beos/beos_options.h"
//#include "beos/beos_completion.h"
#include "beos/beos_throbber.h"
//#include "beos/beos_history.h"
#include "beos/beos_window.h"
//#include "beos/beos_schedule.h"
//#include "beos/beos_download.h"

View File

@ -26,107 +26,59 @@
extern "C" {
#include "utils/config.h"
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
}
const char tree_directory_icon_name[] = "directory.png";
const char tree_content_icon_name[] = "content.png";
/**
* Sets the origin variables to the correct values for a specified tree
* Translates a content_type to the name of a respective icon
*
* \param tree the tree to set the origin for
* \param content_type content type
* \param buffer buffer for the icon name
*/
void tree_initialise_redraw(struct tree *tree) {
}
/**
* Informs the current window manager that an area requires updating.
*
* \param tree the tree that is requesting a redraw
* \param x the x co-ordinate of the redraw area
* \param y the y co-ordinate of the redraw area
* \param width the width of the redraw area
* \param height the height of the redraw area
*/
void tree_redraw_area(struct tree *tree, int x, int y, int width, int height) {
}
/**
* Draws a line.
*
* \param x the x co-ordinate
* \param x the y co-ordinate
* \param x the width of the line
* \param x the height of the line
*/
void tree_draw_line(int x, int y, int width, int height) {
}
/**
* Draws an element, including any expansion icons
*
* \param tree the tree to draw an element for
* \param element the element to draw
*/
void tree_draw_node_element(struct tree *tree, struct node_element *element) {
}
/**
* Draws an elements expansion icon
*
* \param tree the tree to draw the expansion for
* \param element the element to draw the expansion for
*/
void tree_draw_node_expansion(struct tree *tree, struct node *node) {
}
/**
* Recalculates the dimensions of a node element.
*
* \param element the element to recalculate
*/
void tree_recalculate_node_element(struct node_element *element) {
}
/**
* Sets a node element as having a specific sprite.
*
* \param node the node to update
* \param sprite the sprite to use
* \param selected the expanded sprite name to use
*/
void tree_set_node_sprite(struct node *node, const char *sprite,
const char *expanded) {
}
/**
* Sets a node element as having a folder sprite
*
* \param node the node to update
*/
void tree_set_node_sprite_folder(struct node *node) {
}
/**
* Updates the node details for a URL node.
* The internal node dimensions are not updated.
*
* \param node the node to update
*/
void tree_update_URL_node(struct node *node, const char *url,
const struct url_data *data) {
}
/**
* Updates the tree owner following a tree resize
*
* \param tree the tree to update the owner of
*/
void tree_resized(struct tree *tree) {
void tree_icon_name_from_content_type(char *buffer, content_type type)
{
// TODO: design/acquire icons
switch (type) {
case CONTENT_HTML:
case CONTENT_TEXTPLAIN:
case CONTENT_CSS:
#if defined(WITH_MNG) || defined(WITH_PNG)
case CONTENT_PNG:
#endif
#ifdef WITH_MNG
case CONTENT_JNG:
case CONTENT_MNG:
#endif
#ifdef WITH_JPEG
case CONTENT_JPEG:
#endif
#ifdef WITH_GIF
case CONTENT_GIF:
#endif
#ifdef WITH_BMP
case CONTENT_BMP:
case CONTENT_ICO:
#endif
#ifdef WITH_SPRITE
case CONTENT_SPRITE:
#endif
#ifdef WITH_DRAW
case CONTENT_DRAW:
#endif
#ifdef WITH_ARTWORKS
case CONTENT_ARTWORKS:
#endif
#ifdef WITH_NS_SVG
case CONTENT_SVG:
#endif
default:
sprintf(buffer, tree_content_icon_name);
break;
}
}

View File

@ -245,13 +245,11 @@ static bool urldb_iterate_partial_path(const struct path_data *parent,
static bool urldb_iterate_entries_host(struct search_node *parent,
bool (*url_callback)(const char *url,
const struct url_data *data),
bool (*cookie_callback)(const char *domain,
const struct cookie_data *data));
bool (*cookie_callback)(const struct cookie_data *data));
static bool urldb_iterate_entries_path(const struct path_data *parent,
bool (*url_callback)(const char *url,
const struct url_data *data),
bool (*cookie_callback)(const char *domain,
const struct cookie_data *data));
bool (*cookie_callback)(const struct cookie_data *data));
/* Insertion */
static struct host_part *urldb_add_host_node(const char *part,
@ -1390,8 +1388,7 @@ void urldb_iterate_entries(bool (*callback)(const char *url,
*
* \param callback Function to callback for each entry
*/
void urldb_iterate_cookies(bool (*callback)(const char *domain,
const struct cookie_data *data))
void urldb_iterate_cookies(bool (*callback)(const struct cookie_data *data))
{
int i;
@ -1415,8 +1412,7 @@ void urldb_iterate_cookies(bool (*callback)(const char *domain,
bool urldb_iterate_entries_host(struct search_node *parent,
bool (*url_callback)(const char *url,
const struct url_data *data),
bool (*cookie_callback)(const char *domain,
const struct cookie_data *data))
bool (*cookie_callback)(const struct cookie_data *data))
{
if (parent == &empty)
return true;
@ -1452,11 +1448,11 @@ bool urldb_iterate_entries_host(struct search_node *parent,
bool urldb_iterate_entries_path(const struct path_data *parent,
bool (*url_callback)(const char *url,
const struct url_data *data),
bool (*cookie_callback)(const char *domain,
const struct cookie_data *data))
bool (*cookie_callback)(const struct cookie_data *data))
{
const struct path_data *p = parent;
const struct cookie_data *c;
do {
if (p->children != NULL) {
/* Drill down into children */
@ -1478,11 +1474,10 @@ bool urldb_iterate_entries_path(const struct path_data *parent,
(const struct url_data *) u))
return false;
} else {
if (p->cookies && !cookie_callback(
p->cookies->domain,
(const struct cookie_data *)
p->cookies))
return false;
c = (const struct cookie_data *)p->cookies;
for (; c != NULL; c = c->next)
if (!cookie_callback(c))
return false;
}
/* Now, find next node to process. */
@ -2447,9 +2442,7 @@ char *urldb_get_cookie(const char *url)
url_func_result res;
int i;
assert(url);
// LOG(("%s", url));
assert(url != NULL);
urldb_add_url(url);
@ -2529,14 +2522,11 @@ char *urldb_get_cookie(const char *url)
version = c->version;
c->last_used = now;
cookies_update(c->domain,
(struct cookie_data *)c);
cookies_schedule_update((struct cookie_data *)c);
}
}
}
// LOG(("%s", ret));
/* Now consider cookies whose paths prefix-match ours */
for (p = p->parent; p; p = p->parent) {
/* Find directory's path entry(ies) */
@ -2546,7 +2536,6 @@ char *urldb_get_cookie(const char *url)
continue;
for (c = q->cookies; c; c = c->next) {
// LOG(("%p: %s=%s", c, c->name, c->value));
if (c->expires != 1 && c->expires < now)
/* cookie has expired => ignore */
continue;
@ -2565,8 +2554,7 @@ char *urldb_get_cookie(const char *url)
version = c->version;
c->last_used = now;
cookies_update(c->domain,
(struct cookie_data *)c);
cookies_schedule_update((struct cookie_data *)c);
}
}
@ -2606,13 +2594,11 @@ char *urldb_get_cookie(const char *url)
version = c->version;
c->last_used = now;
cookies_update(c->domain, (struct cookie_data *)c);
cookies_schedule_update((struct cookie_data *)c);
}
}
// LOG(("%s", ret));
/* Finally consider domain cookies for hosts which domain match ours */
for (h = (const struct host_part *)p; h && h != &db_root;
h = h->parent) {
@ -2638,12 +2624,10 @@ char *urldb_get_cookie(const char *url)
version = c->version;
c->last_used = now;
cookies_update(c->domain, (struct cookie_data *)c);
cookies_schedule_update((struct cookie_data *)c);
}
}
// LOG(("%s", ret));
if (count == 0) {
/* No cookies found */
free(path);
@ -2712,8 +2696,6 @@ bool urldb_set_cookie(const char *header, const char *url,
assert(url && header);
// LOG(("'%s' : '%s'", url, header));
/* strip fragment */
urlt = strdup(url);
if (!urlt)
@ -2928,7 +2910,7 @@ bool urldb_set_cookie(const char *header, const char *url,
/* Now insert into database */
if (!urldb_insert_cookie(c, scheme, urlt))
goto error;
cookies_update(c->domain, (struct cookie_data *)c);
cookies_schedule_update((struct cookie_data *)c);
} while (cur < end);
free(host);
@ -3378,6 +3360,8 @@ bool urldb_insert_cookie(struct cookie_internal_data *c, const char *scheme,
d->prev->next = d->next;
else
p->cookies = d->next;
cookies_remove((struct cookie_data *)d);
urldb_free_cookie(d);
urldb_free_cookie(c);
} else {
@ -3392,8 +3376,11 @@ bool urldb_insert_cookie(struct cookie_internal_data *c, const char *scheme,
c->prev->next = c;
else
p->cookies = c;
cookies_remove((struct cookie_data *)d);
urldb_free_cookie(d);
// LOG(("%p: %s=%s", c, c->name, c->value));
cookies_schedule_update((struct cookie_data *)c);
}
} else {
c->prev = p->cookies_end;
@ -3403,7 +3390,6 @@ bool urldb_insert_cookie(struct cookie_internal_data *c, const char *scheme,
else
p->cookies = c;
p->cookies_end = c;
// LOG(("%p: %s=%s", c, c->name, c->value));
}
return true;
@ -3771,9 +3757,7 @@ void urldb_delete_cookie_paths(const char *domain, const char *path,
else
p->cookies_end = c->prev;
if (p->cookies == NULL)
cookies_update(domain, NULL);
cookies_remove((struct cookie_data *)c);
urldb_free_cookie(c);
return;

View File

@ -108,8 +108,7 @@ void urldb_iterate_partial(const char *prefix,
/* Iteration */
void urldb_iterate_entries(bool (*callback)(const char *url,
const struct url_data *data));
void urldb_iterate_cookies(bool (*callback)(const char *domain,
const struct cookie_data *cookie));
void urldb_iterate_cookies(bool (*callback)(const struct cookie_data *cookie));
/* Debug */
void urldb_dump(void);

View File

@ -46,6 +46,7 @@
#include "desktop/download.h"
#include "desktop/frames.h"
#include "desktop/history_core.h"
#include "desktop/hotlist.h"
#include "desktop/gui.h"
#include "desktop/options.h"
#include "desktop/selection.h"

531
desktop/cookies.c Normal file
View File

@ -0,0 +1,531 @@
/*
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Cookies (implementation).
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/cookies.h"
#include "desktop/options.h"
#include "desktop/tree.h"
#include "utils/messages.h"
#include "utils/log.h"
#include "utils/url.h"
#include "utils/utils.h"
/** Flags for each type of cookie tree node. */
enum tree_element_cookie {
TREE_ELEMENT_PERSISTENT = 0x01,
TREE_ELEMENT_VERSION = 0x02,
TREE_ELEMENT_SECURE = 0x03,
TREE_ELEMENT_LAST_USED = 0x04,
TREE_ELEMENT_EXPIRES = 0x05,
TREE_ELEMENT_PATH = 0x06,
TREE_ELEMENT_DOMAIN = 0x07,
TREE_ELEMENT_COMMENT = 0x08,
TREE_ELEMENT_VALUE = 0x09,
};
static struct tree *cookies_tree;
static struct node *cookies_tree_root;
static bool user_delete;
static hlcache_handle *folder_icon;
static hlcache_handle *cookie_icon;
/**
* Find an entry in the cookie tree
*
* \param node the node to check the children of
* \param title The title to find
* \return Pointer to node, or NULL if not found
*/
static struct node *cookies_find(struct node *node, const char *title)
{
struct node *search;
struct node_element *element;
for (search = tree_node_get_child(node); search;
search = tree_node_get_next(search)) {
element = tree_node_find_element(search, TREE_ELEMENT_TITLE,
NULL);
if (strcmp(title, tree_node_element_get_text(element)) == 0)
return search;
}
return NULL;
}
/**
* Callback for all cookie tree nodes.
*/
static node_callback_resp cookies_node_callback(void *user_data, struct node_msg_data *msg_data)
{
struct node *node = msg_data->node;
struct node_element *domain, *path;
const char *domain_t, *path_t, *name_t;
char *space;
bool is_folder = tree_node_is_folder(node);
/* we don't remove any icons here */
if (msg_data->msg == NODE_DELETE_ELEMENT_IMG)
return NODE_CALLBACK_HANDLED;
/* let the tree handle events other than text data removal */
if (msg_data->msg != NODE_DELETE_ELEMENT_TXT)
return NODE_CALLBACK_NOT_HANDLED;
/* check if it's a domain folder */
if (is_folder)
return NODE_CALLBACK_NOT_HANDLED;
switch (msg_data->flag) {
case TREE_ELEMENT_TITLE:
if (!user_delete)
break;
/* get the rest of the cookie data */
domain = tree_node_find_element(node,
TREE_ELEMENT_DOMAIN, NULL);
path = tree_node_find_element(node, TREE_ELEMENT_PATH,
NULL);
if ((domain != NULL) &&
(path != NULL)) {
domain_t = tree_node_element_get_text(domain) +
strlen(messages_get(
"TreeDomain")) - 4;
space = strchr(domain_t, ' ');
if (space != NULL)
*space = '\0';
path_t = tree_node_element_get_text(path) +
strlen(messages_get("TreePath"))
- 4;
space = strchr(path_t, ' ');
if (space != NULL)
*space = '\0';
name_t = msg_data->data.text;
urldb_delete_cookie(domain_t, path_t, name_t);
}
break;
default:
break;
}
free(msg_data->data.text);
return NODE_CALLBACK_HANDLED;
}
/**
* Updates a tree entry for a cookie.
*
* All information is copied from the cookie_data, and as such can
* be edited and should be freed.
*
* \param node The node to update
* \param data The cookie data to use
* \return true if node updated, or false for failure
*/
static bool cookies_update_cookie_node(struct node *node,
const struct cookie_data *data)
{
struct node_element *element;
char buffer[32];
assert(data != NULL);
/* update the value text */
element = tree_node_find_element(node, TREE_ELEMENT_VALUE, NULL);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeValue",
data->value != NULL ?
data->value :
messages_get("TreeUnused")));
/* update the comment text */
if ((data->comment != NULL) &&
(strcmp(data->comment, "") != 0)) {
element = tree_node_find_element(node, TREE_ELEMENT_COMMENT, NULL);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeComment",
data->comment));
}
/* update domain text */
element = tree_node_find_element(node, TREE_ELEMENT_DOMAIN, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeDomain",
data->domain,
data->domain_from_set ?
messages_get("TreeHeaders") :
""));
/* update path text */
element = tree_node_find_element(node, TREE_ELEMENT_PATH, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreePath", data->path,
data->path_from_set ?
messages_get("TreeHeaders") :
""));
/* update expiry text */
element = tree_node_find_element(node, TREE_ELEMENT_EXPIRES, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeExpires",
(data->expires > 0)
? (data->expires == 1)
? messages_get("TreeSession")
: ctime(&data->expires)
: messages_get("TreeUnknown")));
/* update last used text */
element = tree_node_find_element(node, TREE_ELEMENT_LAST_USED, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeLastUsed",
(data->last_used > 0) ?
ctime(&data->last_used) :
messages_get("TreeUnknown")));
/* update secure text */
element = tree_node_find_element(node, TREE_ELEMENT_SECURE, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeSecure",
data->secure ?
messages_get("Yes") :
messages_get("No")));
/* update version text */
element = tree_node_find_element(node, TREE_ELEMENT_VERSION, element);
snprintf(buffer, sizeof(buffer), "TreeVersion%i", data->version);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreeVersion",
messages_get(buffer)));
/* update persistant text */
element = tree_node_find_element(node, TREE_ELEMENT_PERSISTENT, element);
tree_update_element_text(cookies_tree,
element,
messages_get_buff("TreePersistent",
data->no_destroy ?
messages_get("Yes") :
messages_get("No")));
return node;
}
/**
* Creates an empty tree entry for a cookie, and links it into the tree.
*
* All information is copied from the cookie_data, and as such can
* be edited and should be freed.
*
* \param parent the node to link to
* \param data the cookie data to use
* \return the node created, or NULL for failure
*/
static struct node *cookies_create_cookie_node(struct node *parent,
const struct cookie_data *data)
{
struct node *node;
char *name;
name = strdup(data->name);
if (name == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NULL;
}
node = tree_create_leaf_node(cookies_tree, NULL, name,
false, false, false);
if (node == NULL) {
free(name);
return NULL;
}
tree_set_node_user_callback(node, cookies_node_callback, NULL);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_PERSISTENT, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_VERSION, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SECURE, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_LAST_USED, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_EXPIRES, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_PATH, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_DOMAIN, false);
if ((data->comment) && (strcmp(data->comment, "")))
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_COMMENT, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_VALUE, false);
tree_set_node_icon(cookies_tree, node, cookie_icon);
if (!cookies_update_cookie_node(node, data))
{
tree_delete_node(NULL, node, false);
return NULL;
}
tree_link_node(cookies_tree, parent, node, false);
return node;
}
/**
* Called when scheduled event gets fired. Actually performs the update.
*/
static void cookies_schedule_callback(void *scheduled_data)
{
const struct cookie_data *data = scheduled_data;
struct node *node = NULL;
struct node *cookie_node = NULL;
char *domain_cp;
assert(data != NULL);
node = cookies_find(cookies_tree_root, data->domain);
if (node == NULL) {
domain_cp = strdup(data->domain);
if (domain_cp == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return;
}
node = tree_create_folder_node(cookies_tree,
cookies_tree_root, domain_cp,
false, false, false);
if (node != NULL) {
tree_set_node_user_callback(node, cookies_node_callback,
NULL);
tree_set_node_icon(cookies_tree, node, folder_icon);
}
}
if (node == NULL)
return;
cookie_node = cookies_find(node, data->name);
if (cookie_node == NULL)
cookies_create_cookie_node(node, data);
else
cookies_update_cookie_node(cookie_node, data);
return;
}
/**
* Initialises cookies tree.
*
* \param data user data for the callbacks
* \param start_redraw callback function called before every redraw
* \param end_redraw callback function called after every redraw
* \return true on success, false on memory exhaustion
*/
bool cookies_initialise(struct tree *tree)
{
if (tree == NULL)
return false;
folder_icon = tree_load_icon(tree_directory_icon_name);
cookie_icon = tree_load_icon(tree_content_icon_name);
/* Create an empty tree */
cookies_tree = tree;
cookies_tree_root = tree_get_root(cookies_tree);
user_delete = false;
urldb_iterate_cookies(cookies_schedule_update);
tree_set_node_expanded(cookies_tree, cookies_tree_root,
true, true, true);
return true;
}
/**
* Get flags with which the cookies tree should be created;
*
* \return the flags
*/
unsigned int cookies_get_tree_flags(void)
{
return TREE_DELETE_EMPTY_DIRS;
}
/* exported interface documented in cookies.h */
bool cookies_schedule_update(const struct cookie_data *data)
{
assert(data != NULL);
assert(user_delete == false);
schedule(100, cookies_schedule_callback, (void *)data);
return true;
}
/* exported interface documented in cookies.h */
void cookies_remove(const struct cookie_data *data)
{
assert(data != NULL);
schedule_remove(cookies_schedule_callback, (void *)data);
}
/**
* Free memory and release all other resources.
*/
void cookies_cleanup(void)
{
}
/* Actions to be connected to front end specific toolbars */
/**
* Delete nodes which are currently selected.
*/
void cookies_delete_selected(void)
{
user_delete = true;
tree_delete_selected_nodes(cookies_tree, cookies_tree_root);
user_delete = false;
}
/**
* Delete all nodes.
*/
void cookies_delete_all(void)
{
bool needs_redraw = tree_get_redraw(cookies_tree);
if (needs_redraw)
tree_set_redraw(cookies_tree, false);
user_delete = true;
tree_set_node_selected(cookies_tree, cookies_tree_root, true, true);
tree_delete_selected_nodes(cookies_tree, cookies_tree_root);
user_delete = false;
if (needs_redraw)
tree_set_redraw(cookies_tree, true);
}
/**
* Select all nodes in the tree.
*/
void cookies_select_all(void)
{
tree_set_node_selected(cookies_tree, cookies_tree_root, true, true);
}
/**
* Unselect all nodes.
*/
void cookies_clear_selection(void)
{
tree_set_node_selected(cookies_tree, cookies_tree_root, true, false);
}
/**
* Expand both domain and cookie nodes.
*/
void cookies_expand_all(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
true, true, true);
}
/**
* Expand domain nodes only.
*/
void cookies_expand_domains(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
true, true, false);
}
/**
* Expand cookie nodes only.
*/
void cookies_expand_cookies(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
true, false, true);
}
/**
* Collapse both domain and cookie nodes.
*/
void cookies_collapse_all(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
false, true, true);
}
/**
* Collapse domain nodes only.
*/
void cookies_collapse_domains(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
false, true, false);
}
/**
* Collapse cookie nodes only.
*/
void cookies_collapse_cookies(void)
{
tree_set_node_expanded(cookies_tree, cookies_tree_root,
false, false, true);
}

View File

@ -25,8 +25,42 @@
#include <stdbool.h>
#include "desktop/tree.h"
struct cookie_data;
bool cookies_update(const char *domain, const struct cookie_data *data);
bool cookies_initialise(struct tree *tree);
unsigned int cookies_get_tree_flags(void);
/**
* Perform cookie updates and addition. The update is only scheduled here.
* The actual update is performed in the callback function.
*
* \param data Data of cookie being updated.
* \return true (for urldb_iterate_entries)
*/
bool cookies_schedule_update(const struct cookie_data *data);
/**
* Remove a cookie from the active set.
* The cookie is to be removed from the active set and no futher
* references made to the cookie data.
*
* \param data Data of cookie being removed.
*/
void cookies_remove(const struct cookie_data *data);
void cookies_cleanup(void);
void cookies_delete_selected(void);
void cookies_delete_all(void);
void cookies_select_all(void);
void cookies_clear_selection(void);
void cookies_expand_all(void);
void cookies_expand_domains(void);
void cookies_expand_cookies(void);
void cookies_collapse_all(void);
void cookies_collapse_domains(void);
void cookies_collapse_cookies(void);
#endif

View File

@ -0,0 +1,464 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/history_global_core.h"
#include "desktop/plotters.h"
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
#ifdef riscos
#include "riscos/gui.h"
#endif
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/log.h"
#define MAXIMUM_BASE_NODES 16
#define GLOBAL_HISTORY_RECENT_URLS 16
#define URL_CHUNK_LENGTH 512
static struct node *global_history_base_node[MAXIMUM_BASE_NODES];
static int global_history_base_node_time[MAXIMUM_BASE_NODES];
static int global_history_base_node_count = 0;
static bool global_history_initialised;
static struct tree *global_history_tree;
static struct node *global_history_tree_root;
static hlcache_handle *folder_icon;
static const char *const weekday_msg_name [] =
{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
/**
* Find an entry in the global history
*
* \param url The URL to find
* \return Pointer to node, or NULL if not found
*/
static struct node *history_global_find(const char *url)
{
int i;
struct node *node;
const char *text;
for (i = 0; i < global_history_base_node_count; i++) {
if (!tree_node_is_deleted(global_history_base_node[i])) {
node = tree_node_get_child(global_history_base_node[i]);
for (; node != NULL; node = tree_node_get_next(node)) {
text = tree_url_node_get_url(node);
if ((text != NULL) && !strcmp(url, text))
return node;
}
}
}
return NULL;
}
/**
* Internal routine to actually perform global history addition
*
* \param url The URL to add
* \param data URL data associated with URL
* \return true (for urldb_iterate_entries)
*/
static bool global_history_add_internal(const char *url,
const struct url_data *data)
{
int i, j;
struct node *parent = NULL;
struct node *link;
struct node *node;
bool before = false;
int visit_date;
assert((url != NULL) && (data != NULL));
visit_date = data->last_visit;
/* find parent node */
for (i = 0; i < global_history_base_node_count; i++) {
if (global_history_base_node_time[i] <= visit_date) {
parent = global_history_base_node[i];
break;
}
}
/* the entry is too old to care about */
if (parent == NULL)
return true;
if (tree_node_is_deleted(parent)) {
/* parent was deleted, so find place to insert it */
link = global_history_tree_root;
for (j = global_history_base_node_count - 1; j >= 0; j--) {
if (!tree_node_is_deleted(global_history_base_node[j]) &&
global_history_base_node_time[j] >
global_history_base_node_time[i]) {
link = global_history_base_node[j];
before = true;
break;
}
}
tree_set_node_selected(global_history_tree,
parent, true, false);
tree_set_node_expanded(global_history_tree,
parent, false, true, true);
tree_link_node(global_history_tree, link, parent, before);
}
/* find any previous occurance */
if (global_history_initialised == false) {
node = history_global_find(url);
if (node != NULL) {
tree_update_URL_node(global_history_tree,
node, url, data, true);
tree_delink_node(global_history_tree, node);
tree_link_node(global_history_tree, parent, node,
false);
return true;
}
}
/* Add the node at the bottom */
node = tree_create_URL_node_shared(global_history_tree,
parent, url, data,
tree_url_node_callback, NULL);
return true;
}
static node_callback_resp
history_global_node_callback(void *user_data,
struct node_msg_data *msg_data)
{
if (msg_data->msg == NODE_DELETE_ELEMENT_IMG)
return NODE_CALLBACK_HANDLED;
return NODE_CALLBACK_NOT_HANDLED;
}
/**
* Initialises a single grouping node for the global history tree.
*
* \return false on memory exhaustion, true otherwise
*/
static bool history_global_initialise_node(const char *title,
time_t base, int days_back)
{
struct tm *full_time;
char *buffer;
struct node *node;
base += days_back * 60 * 60 * 24;
if (title == NULL) {
full_time = localtime(&base);
buffer = strdup(messages_get(weekday_msg_name[full_time->tm_wday]));
} else {
buffer = strdup(title);
}
if (buffer == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return false;
}
node = tree_create_folder_node(NULL, NULL, buffer,
false, true, true);
if (node == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
free(buffer);
return false;
}
if (folder_icon != NULL)
tree_set_node_icon(global_history_tree, node, folder_icon);
tree_set_node_user_callback(node, history_global_node_callback, NULL);
global_history_base_node[global_history_base_node_count] = node;
global_history_base_node_time[global_history_base_node_count] = base;
global_history_base_node_count++;
return true;
}
/**
* Initialises the grouping nodes(Today, Yesterday etc.) for the global history
* tree.
*
* \return false on memory exhaustion, true otherwise
*/
static bool history_global_initialise_nodes(void)
{
struct tm *full_time;
time_t t;
int weekday;
int i;
/* get the current time */
t = time(NULL);
if (t == -1) {
LOG(("time info unaviable"));
return false;
}
/* get the time at the start of today */
full_time = localtime(&t);
weekday = full_time->tm_wday;
full_time->tm_sec = 0;
full_time->tm_min = 0;
full_time->tm_hour = 0;
t = mktime(full_time);
if (t == -1) {
LOG(("mktime failed"));
return false;
}
history_global_initialise_node(messages_get("DateToday"), t, 0);
if (weekday > 0)
if (!history_global_initialise_node(
messages_get("DateYesterday"), t, -1))
return false;
for (i = 2; i <= weekday; i++)
if (!history_global_initialise_node(NULL, t, -i))
return false;
if (!history_global_initialise_node(messages_get("Date1Week"),
t, -weekday - 7))
return false;
if (!history_global_initialise_node(messages_get("Date2Week"),
t, -weekday - 14))
return false;
if (!history_global_initialise_node(messages_get("Date3Week"),
t, -weekday - 21))
return false;
return true;
}
/**
* Initialises the global history tree.
*
* \param data user data for the callbacks
* \param start_redraw callback function called before every redraw
* \param end_redraw callback function called after every redraw
* \return true on success, false on memory exhaustion
*/
bool history_global_initialise(struct tree *tree)
{
struct node *first;
folder_icon = tree_load_icon(tree_directory_icon_name);
tree_url_node_init();
if (tree == NULL)
return false;
global_history_tree = tree;
global_history_tree_root = tree_get_root(global_history_tree);
if (!history_global_initialise_nodes())
return false;
global_history_initialised = true;
urldb_iterate_entries(global_history_add_internal);
global_history_initialised = false;
tree_set_node_expanded(global_history_tree, global_history_tree_root,
false, true, true);
first = tree_node_get_child(global_history_tree_root);
if (first != NULL)
tree_set_node_expanded(global_history_tree, first,
true, false, false);
return true;
}
/**
* Get flags with which the global history tree should be created;
*
* \return the flags
*/
unsigned int history_global_get_tree_flags(void)
{
return TREE_NO_FLAGS;
}
/**
* Deletes the global history tree.
*/
void history_global_cleanup(void)
{
}
/**
* Adds a url to the global history.
*
* \param url the url to be added
*/
void global_history_add(const char *url)
{
const struct url_data *data;
data = urldb_get_url_data(url);
if (data == NULL)
return;
global_history_add_internal(url, data);
}
/* Actions to be connected to front end specific toolbars */
/**
* Save the global history in a human-readable form under the given location.
*
* \param path the path where the history will be saved
*/
bool history_global_export(const char *path)
{
return tree_urlfile_save(global_history_tree, path, "NetSurf history");
}
/**
* Delete nodes which are currently selected.
*/
void history_global_delete_selected(void)
{
tree_delete_selected_nodes(global_history_tree,
global_history_tree_root);
}
/**
* Delete all nodes.
*/
void history_global_delete_all(void)
{
bool redraw_needed = tree_get_redraw(global_history_tree);
if (redraw_needed)
tree_set_redraw(global_history_tree, false);
tree_set_node_selected(global_history_tree, global_history_tree_root,
true, true);
tree_delete_selected_nodes(global_history_tree,
global_history_tree_root);
if (redraw_needed)
tree_set_redraw(global_history_tree, true);
}
/**
* Select all nodes in the tree.
*/
void history_global_select_all(void)
{
tree_set_node_selected(global_history_tree, global_history_tree_root,
true, true);
}
/**
* Unselect all nodes.
*/
void history_global_clear_selection(void)
{
tree_set_node_selected(global_history_tree, global_history_tree_root,
true, false);
}
/**
* Expand grouping folders and history entries.
*/
void history_global_expand_all(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
true, true, true);
}
/**
* Expand grouping folders only.
*/
void history_global_expand_directories(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
true, true, false);
}
/**
* Expand history entries only.
*/
void history_global_expand_addresses(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
true, false, true);
}
/**
* Collapse grouping folders and history entries.
*/
void history_global_collapse_all(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
false, true, true);
}
/**
* Collapse grouping folders only.
*/
void history_global_collapse_directories(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
false, true, false);
}
/**
* Collapse history entries only.
*/
void history_global_collapse_addresses(void)
{
tree_set_node_expanded(global_history_tree, global_history_tree_root,
false, false, true);
}
/**
* Open the selected entries in seperate browser windows.
*/
void history_global_launch_selected(void)
{
tree_launch_selected(global_history_tree);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NETSURF_DESKTOP_HISTORY_GLOBAL_H_
#define _NETSURF_DESKTOP_HISTORY_GLOBAL_H_
#include <stdbool.h>
#include "desktop/tree.h"
bool history_global_initialise(struct tree *tree);
unsigned int history_global_get_tree_flags(void);
void history_global_cleanup(void);
bool history_global_export(const char *path);
void history_global_delete_selected(void);
void history_global_delete_all(void);
void history_global_select_all(void);
void history_global_clear_selection(void);
void history_global_expand_all(void);
void history_global_expand_directories(void);
void history_global_expand_addresses(void);
void history_global_collapse_all(void);
void history_global_collapse_directories(void);
void history_global_collapse_addresses(void);
void history_global_launch_selected(void);
#endif

457
desktop/hotlist.c Normal file
View File

@ -0,0 +1,457 @@
/*
* Copyright 2004, 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ctype.h>
#include <stdlib.h>
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/hotlist.h"
#include "desktop/plotters.h"
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/log.h"
#define URL_CHUNK_LENGTH 512
static struct tree *hotlist_tree;
static struct node *hotlist_tree_root;
static bool creating_node;
static hlcache_handle *folder_icon;
static const struct {
const char *url;
const char *msg_key;
} hotlist_default_entries[] = {
{ "http://www.netsurf-browser.org/", "HotlistHomepage" },
{ "http://www.netsurf-browser.org/downloads/riscos/testbuilds",
"HotlistTestBuild" },
{ "http://www.netsurf-browser.org/documentation",
"HotlistDocumentation" },
{ "http://sourceforge.net/tracker/?atid=464312&group_id=51719",
"HotlistBugTracker" },
{ "http://sourceforge.net/tracker/?atid=464315&group_id=51719",
"HotlistFeatureRequest" }
};
#define HOTLIST_ENTRIES_COUNT (sizeof(hotlist_default_entries) / sizeof(hotlist_default_entries[0]))
static node_callback_resp hotlist_node_callback(void *user_data,
struct node_msg_data *msg_data)
{
struct node *node = msg_data->node;
const char *text;
char *norm_text;
bool is_folder = tree_node_is_folder(node);
switch (msg_data->msg) {
case NODE_ELEMENT_EDIT_FINISHED:
if (creating_node &&
(is_folder == false) &&
(msg_data->flag == TREE_ELEMENT_TITLE)) {
tree_url_node_edit_url(hotlist_tree, node);
} else {
creating_node = false;
}
return NODE_CALLBACK_HANDLED;
case NODE_ELEMENT_EDIT_FINISHING:
if (creating_node && (is_folder == false))
return tree_url_node_callback(hotlist_tree, msg_data);
if (is_folder == true) {
text = msg_data->data.text;
while (isspace(*text))
text++;
norm_text = strdup(text);
if (norm_text == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NODE_CALLBACK_REJECT;
}
/* don't allow zero length entry text, return false */
if (norm_text[0] == '\0') {
warn_user("NoNameError", 0);
msg_data->data.text = NULL;
return NODE_CALLBACK_CONTINUE;
}
msg_data->data.text = norm_text;
}
break;
case NODE_DELETE_ELEMENT_IMG:
return NODE_CALLBACK_HANDLED;
default:
if (is_folder == false)
return tree_url_node_callback(hotlist_tree, msg_data);
}
return NODE_CALLBACK_NOT_HANDLED;
}
bool hotlist_initialise(struct tree *tree, const char *hotlist_path)
{
struct node *node;
const struct url_data *url_data;
char *name;
int hlst_loop;
/* Either load or create a hotlist */
creating_node = false;
folder_icon = tree_load_icon(tree_directory_icon_name);
tree_url_node_init();
if (tree == NULL)
return false;
hotlist_tree = tree;
hotlist_tree_root = tree_get_root(hotlist_tree);
if (tree_urlfile_load(hotlist_path,
hotlist_tree,
hotlist_node_callback,
NULL)) {
return true;
}
/* failed to load hotlist file, use default list */
name = strdup("NetSurf");
if (name == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return false;
}
node = tree_create_folder_node(hotlist_tree, hotlist_tree_root,
name, true, false, false);
if (node == NULL) {
free(name);
return false;
}
tree_set_node_user_callback(node, hotlist_node_callback, NULL);
tree_set_node_icon(hotlist_tree, node, folder_icon);
for (hlst_loop = 0; hlst_loop != HOTLIST_ENTRIES_COUNT; hlst_loop++) {
url_data = urldb_get_url_data(hotlist_default_entries[hlst_loop].url);
if (url_data == NULL) {
urldb_add_url(hotlist_default_entries[hlst_loop].url);
urldb_set_url_persistence(
hotlist_default_entries[hlst_loop].url,
true);
url_data = urldb_get_url_data(
hotlist_default_entries[hlst_loop].url);
}
if (url_data != NULL) {
tree_create_URL_node(hotlist_tree, node,
hotlist_default_entries[hlst_loop].url,
messages_get(hotlist_default_entries[hlst_loop].msg_key),
hotlist_node_callback, NULL);
tree_update_URL_node(hotlist_tree, node,
hotlist_default_entries[hlst_loop].url,
url_data, false);
}
}
return true;
}
/**
* Get flags with which the hotlist tree should be created;
*
* \return the flags
*/
unsigned int hotlist_get_tree_flags(void)
{
return TREE_MOVABLE;
}
/**
* Deletes the global history tree and saves the hotlist.
* \param hotlist_path the path where the hotlist should be saved
*/
void hotlist_cleanup(const char *hotlist_path)
{
hotlist_export(hotlist_path);
}
/**
* Informs the hotlist that some content has been visited. Internal procedure.
*
* \param content the content visited
* \param node the node to update siblings and children of
*/
static void hotlist_visited_internal(hlcache_handle *content, struct node *node)
{
struct node *child;
const char *text;
const char *url;
if (content == NULL ||
content_get_url(content) == NULL ||
hotlist_tree == NULL)
return;
url = content_get_url(content);
for (; node; node = tree_node_get_next(node)) {
if (!tree_node_is_folder(node)) {
text = tree_url_node_get_url(node);
if (strcmp(text, url) == 0) {
tree_update_URL_node(hotlist_tree, node,
url, NULL, false);
}
}
child = tree_node_get_child(node);
if (child != NULL) {
hotlist_visited_internal(content, child);
}
}
}
/**
* Informs the hotlist that some content has been visited
*
* \param content the content visited
*/
void hotlist_visited(hlcache_handle *content)
{
if (hotlist_tree != NULL) {
hotlist_visited_internal(content, tree_get_root(hotlist_tree));
}
}
/**
* Save the hotlist in a human-readable form under the given location.
*
* \param path the path where the hotlist will be saved
*/
bool hotlist_export(const char *path)
{
return tree_urlfile_save(hotlist_tree, path, "NetSurf hotlist");
}
/**
* Edit the node which is currently selected. Works only if one node is
* selected.
*/
void hotlist_edit_selected(void)
{
struct node *node;
struct node_element *element;
node = tree_get_selected_node(hotlist_tree_root);
if (node != NULL) {
creating_node = true;
element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
tree_start_edit(hotlist_tree, element);
}
}
/**
* Delete nodes which are currently selected.
*/
void hotlist_delete_selected(void)
{
tree_delete_selected_nodes(hotlist_tree, hotlist_tree_root);
}
/**
* Select all nodes in the tree.
*/
void hotlist_select_all(void)
{
tree_set_node_selected(hotlist_tree, hotlist_tree_root,
true, true);
}
/**
* Unselect all nodes.
*/
void hotlist_clear_selection(void)
{
tree_set_node_selected(hotlist_tree, hotlist_tree_root,
true, false);
}
/**
* Expand grouping folders and history entries.
*/
void hotlist_expand_all(void)
{
tree_set_node_expanded(hotlist_tree, hotlist_tree_root,
true, true, true);
}
/**
* Expand grouping folders only.
*/
void hotlist_expand_directories(void)
{
tree_set_node_expanded(hotlist_tree, hotlist_tree_root,
true, true, false);
}
/**
* Expand history entries only.
*/
void hotlist_expand_addresses(void)
{
tree_set_node_expanded(hotlist_tree, hotlist_tree_root,
true, false, true);
}
/**
* Collapse grouping folders and history entries.
*/
void hotlist_collapse_all(void)
{
tree_set_node_expanded(hotlist_tree, hotlist_tree_root,
false, true, true);
}
/**
* Collapse grouping folders only.
*/
void hotlist_collapse_directories(void)
{
tree_set_node_expanded(hotlist_tree, hotlist_tree_root,
false, true, false);
}
/**
* Collapse history entries only.
*/
void hotlist_collapse_addresses(void)
{
tree_set_node_expanded(hotlist_tree,
hotlist_tree_root, false, false, true);
}
/**
* Add a folder node.
*/
void hotlist_add_folder(void)
{
struct node *node;
struct node_element *element;
char *title = strdup("Untitled");
if (title == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return;
}
creating_node = true;
node = tree_create_folder_node(hotlist_tree, hotlist_tree_root, title,
true, false, false);
if (node == NULL) {
free(title);
return;
}
tree_set_node_user_callback(node, hotlist_node_callback, NULL);
tree_set_node_icon(hotlist_tree, node, folder_icon);
element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
tree_start_edit(hotlist_tree, element);
}
/**
* Add an entry node.
*/
void hotlist_add_entry(void)
{
struct node *node;
creating_node = true;
node = tree_create_URL_node(hotlist_tree, hotlist_tree_root, "Address",
"Untitled", hotlist_node_callback, NULL);
if (node == NULL)
return;
tree_set_node_user_callback(node, hotlist_node_callback, NULL);
tree_url_node_edit_title(hotlist_tree, node);
}
/**
* Adds the currently viewed page to the hotlist
*/
void hotlist_add_page(const char *url)
{
const struct url_data *data;
struct node *node;
if (url == NULL)
return;
data = urldb_get_url_data(url);
if (data == NULL)
return;
node = tree_create_URL_node(hotlist_tree, hotlist_tree_root, url, NULL,
hotlist_node_callback, NULL);
tree_update_URL_node(hotlist_tree, node, url, data, false);
}
/**
* Adds the currently viewed page to the hotlist at the given cooridinates
* \param url url of the page
* \param x X cooridinate with respect to tree origin
* \param y Y cooridinate with respect to tree origin
*/
void hotlist_add_page_xy(const char *url, int x, int y)
{
const struct url_data *data;
struct node *link, *node;
bool before;
data = urldb_get_url_data(url);
if (data == NULL) {
urldb_add_url(url);
urldb_set_url_persistence(url, true);
data = urldb_get_url_data(url);
}
if (data != NULL) {
link = tree_get_link_details(hotlist_tree, x, y, &before);
node = tree_create_URL_node(NULL, NULL, url,
NULL, hotlist_node_callback, NULL);
tree_link_node(hotlist_tree, link, node, before);
}
}
/**
* Open the selected entries in separate browser windows.
*/
void hotlist_launch_selected(void)
{
tree_launch_selected(hotlist_tree);
}

54
desktop/hotlist.h Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright 2004, 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Hotlist (interface).
*/
#ifndef _NETSURF_DESKTOP_HOTLIST_H_
#define _NETSURF_DESKTOP_HOTLIST_H_
#include <stdbool.h>
#include "desktop/tree.h"
bool hotlist_initialise(struct tree *tree, const char *hotlist_path);
unsigned int hotlist_get_tree_flags(void);
void hotlist_cleanup(const char *hotlist_path);
bool hotlist_export(const char *path);
void hotlist_edit_selected(void);
void hotlist_delete_selected(void);
void hotlist_select_all(void);
void hotlist_clear_selection(void);
void hotlist_expand_all(void);
void hotlist_expand_directories(void);
void hotlist_expand_addresses(void);
void hotlist_collapse_all(void);
void hotlist_collapse_directories(void);
void hotlist_collapse_addresses(void);
void hotlist_add_folder(void);
void hotlist_add_entry(void);
void hotlist_add_page(const char *url);
void hotlist_add_page_xy(const char *url, int x, int y);
void hotlist_launch_selected(void);
#endif

View File

@ -31,16 +31,10 @@
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include "content/urldb.h"
#include "css/css.h"
#include "desktop/options.h"
#include "desktop/plot_style.h"
#include "desktop/tree.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/url.h"
#include "utils/utils.h"
#if defined(riscos)
@ -145,6 +139,7 @@ unsigned int option_min_reflow_period = 100; /* time in cs */
#else
unsigned int option_min_reflow_period = 25; /* time in cs */
#endif
char *option_tree_icons_dir = NULL;
bool option_core_select_menu = false;
/** top margin of exported page*/
int option_margin_top = DEFAULT_MARGIN_TOP_MM;
@ -247,6 +242,7 @@ struct {
{ "scale", OPTION_INTEGER, &option_scale },
{ "incremental_reflow", OPTION_BOOL, &option_incremental_reflow },
{ "min_reflow_period", OPTION_INTEGER, &option_min_reflow_period },
{ "tree_icons_dir", OPTION_STRING, &option_tree_icons_dir },
{ "core_select_menu", OPTION_BOOL, &option_core_select_menu },
/* Fetcher options */
{ "max_fetchers", OPTION_INTEGER, &option_max_fetchers },
@ -276,13 +272,6 @@ struct {
#define option_table_entries (sizeof option_table / sizeof option_table[0])
static void options_load_tree_directory(xmlNode *ul, struct node *directory);
static void options_load_tree_entry(xmlNode *li, struct node *directory);
xmlNode *options_find_tree_element(xmlNode *node, const char *name);
bool options_save_tree_directory(struct node *directory, xmlNode *node);
bool options_save_tree_entry(struct node *entry, xmlNode *node);
/**
* Read options from a file.
*
@ -429,351 +418,3 @@ void options_dump(void)
fprintf(stderr, "\n");
}
}
/**
* Loads a hotlist as a tree from a specified file.
*
* \param filename name of file to read
* \return the hotlist file represented as a tree, or NULL on failure
*/
struct tree *options_load_tree(const char *filename) {
xmlDoc *doc;
xmlNode *html, *body, *ul;
struct tree *tree;
doc = htmlParseFile(filename, "iso-8859-1");
if (!doc) {
warn_user("HotlistLoadError", messages_get("ParsingFail"));
return NULL;
}
html = options_find_tree_element((xmlNode *) doc, "html");
body = options_find_tree_element(html, "body");
ul = options_find_tree_element(body, "ul");
if (!ul) {
xmlFreeDoc(doc);
warn_user("HotlistLoadError",
"(<html>...<body>...<ul> not found.)");
return NULL;
}
tree = calloc(sizeof(struct tree), 1);
if (!tree) {
xmlFreeDoc(doc);
warn_user("NoMemory", 0);
return NULL;
}
tree->root = tree_create_folder_node(NULL, "Root");
if (!tree->root) {
free(tree);
xmlFreeDoc(doc);
return NULL;
}
options_load_tree_directory(ul, tree->root);
tree->root->expanded = true;
tree_initialise(tree);
xmlFreeDoc(doc);
return tree;
}
/**
* Parse a directory represented as a ul.
*
* \param ul xmlNode for parsed ul
* \param directory directory to add this directory to
*/
void options_load_tree_directory(xmlNode *ul, struct node *directory) {
char *title;
struct node *dir;
xmlNode *n;
assert(ul);
assert(directory);
for (n = ul->children; n; n = n->next) {
/* The ul may contain entries as a li, or directories as
* an h4 followed by a ul. Non-element nodes may be present
* (eg. text, comments), and are ignored. */
if (n->type != XML_ELEMENT_NODE)
continue;
if (strcmp((const char *) n->name, "li") == 0) {
/* entry */
options_load_tree_entry(n, directory);
} else if (strcmp((const char *) n->name, "h4") == 0) {
/* directory */
title = (char *) xmlNodeGetContent(n);
if (!title) {
warn_user("HotlistLoadError", "(Empty <h4> "
"or memory exhausted.)");
return;
}
for (n = n->next;
n && n->type != XML_ELEMENT_NODE;
n = n->next)
;
if (!n || strcmp((const char *) n->name, "ul") != 0) {
/* next element isn't expected ul */
free(title);
warn_user("HotlistLoadError", "(Expected "
"<ul> not present.)");
return;
}
dir = tree_create_folder_node(directory, title);
if (!dir) {
free(title);
return;
}
options_load_tree_directory(n, dir);
}
}
}
/**
* Parse an entry represented as a li.
*
* \param li xmlNode for parsed li
* \param directory directory to add this entry to
*/
void options_load_tree_entry(xmlNode *li, struct node *directory) {
char *url = NULL, *url1 = NULL;
char *title = NULL;
struct node *entry;
xmlNode *n;
const struct url_data *data;
url_func_result res;
for (n = li->children; n; n = n->next) {
/* The li must contain an "a" element */
if (n->type == XML_ELEMENT_NODE &&
strcmp((const char *) n->name, "a") == 0) {
url1 = (char *) xmlGetProp(n, (const xmlChar *) "href");
title = (char *) xmlNodeGetContent(n);
}
}
if (!url1 || !title) {
warn_user("HotlistLoadError", "(Missing <a> in <li> or "
"memory exhausted.)");
return;
}
/* We're loading external input.
* This may be garbage, so attempt to normalise
*/
res = url_normalize(url1, &url);
if (res != URL_FUNC_OK) {
LOG(("Failed normalising '%s'", url1));
if (res == URL_FUNC_NOMEM)
warn_user("NoMemory", NULL);
xmlFree(url1);
xmlFree(title);
return;
}
/* No longer need this */
xmlFree(url1);
data = urldb_get_url_data(url);
if (!data) {
/* No entry in database, so add one */
urldb_add_url(url);
/* now attempt to get url data */
data = urldb_get_url_data(url);
}
if (!data) {
xmlFree(title);
free(url);
return;
}
/* Make this URL persistent */
urldb_set_url_persistence(url, true);
if (!data->title)
urldb_set_url_title(url, title);
entry = tree_create_URL_node(directory, url, data, title);
if (entry == NULL) {
/** \todo why isn't this fatal? */
warn_user("NoMemory", 0);
}
xmlFree(title);
free(url);
}
/**
* Search the children of an xmlNode for an element.
*
* \param node xmlNode to search children of, or 0
* \param name name of element to find
* \return first child of node which is an element and matches name, or
* 0 if not found or parameter node is 0
*/
xmlNode *options_find_tree_element(xmlNode *node, const char *name) {
xmlNode *n;
if (!node)
return 0;
for (n = node->children;
n && !(n->type == XML_ELEMENT_NODE &&
strcmp((const char *) n->name, name) == 0);
n = n->next)
;
return n;
}
/**
* Perform a save to a specified file
*
* /param filename the file to save to
*/
bool options_save_tree(struct tree *tree, const char *filename, const char *page_title) {
int res;
xmlDoc *doc;
xmlNode *html, *head, *title, *body;
/* Unfortunately the Browse Hotlist format is invalid HTML,
* so this is a lie. */
doc = htmlNewDoc(
(const xmlChar *) "http://www.w3.org/TR/html4/strict.dtd",
(const xmlChar *) "-//W3C//DTD HTML 4.01//EN");
if (!doc) {
warn_user("NoMemory", 0);
return false;
}
html = xmlNewNode(NULL, (const xmlChar *) "html");
if (!html) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
xmlDocSetRootElement(doc, html);
head = xmlNewChild(html, NULL, (const xmlChar *) "head", NULL);
if (!head) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
title = xmlNewTextChild(head, NULL, (const xmlChar *) "title",
(const xmlChar *) page_title);
if (!title) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
body = xmlNewChild(html, NULL, (const xmlChar *) "body", NULL);
if (!body) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
if (!options_save_tree_directory(tree->root, body)) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
doc->charset = XML_CHAR_ENCODING_UTF8;
res = htmlSaveFileEnc(filename, doc, "iso-8859-1");
if (res == -1) {
warn_user("HotlistSaveError", 0);
xmlFreeDoc(doc);
return false;
}
xmlFreeDoc(doc);
return true;
}
/**
* Add a directory to the HTML tree for saving.
*
* \param directory hotlist directory to add
* \param node node to add ul to
* \return true on success, false on memory exhaustion
*/
bool options_save_tree_directory(struct node *directory, xmlNode *node) {
struct node *child;
xmlNode *ul, *h4;
ul = xmlNewChild(node, NULL, (const xmlChar *) "ul", NULL);
if (!ul)
return false;
for (child = directory->child; child; child = child->next) {
if (!child->folder) {
/* entry */
if (!options_save_tree_entry(child, ul))
return false;
} else {
/* directory */
/* invalid HTML */
h4 = xmlNewTextChild(ul, NULL,
(const xmlChar *) "h4",
(const xmlChar *) child->data.text);
if (!h4)
return false;
if (!options_save_tree_directory(child, ul))
return false;
} }
return true;
}
/**
* Add an entry to the HTML tree for saving.
*
* The node must contain a sequence of node_elements in the following order:
*
* \param entry hotlist entry to add
* \param node node to add li to
* \return true on success, false on memory exhaustion
*/
bool options_save_tree_entry(struct node *entry, xmlNode *node) {
xmlNode *li, *a;
xmlAttr *href;
struct node_element *element;
li = xmlNewChild(node, NULL, (const xmlChar *) "li", NULL);
if (!li)
return false;
a = xmlNewTextChild(li, NULL, (const xmlChar *) "a",
(const xmlChar *) entry->data.text);
if (!a)
return false;
element = tree_find_element(entry, TREE_ELEMENT_URL);
if (!element)
return false;
href = xmlNewProp(a, (const xmlChar *) "href",
(const xmlChar *) element->text);
if (!href)
return false;
return true;
}

View File

@ -85,6 +85,7 @@ extern int option_toolbar_status_width;
extern int option_scale;
extern bool option_incremental_reflow;
extern unsigned int option_min_reflow_period;
extern char *option_tree_icons_dir;
extern bool option_core_select_menu;
extern int option_margin_top;
@ -114,8 +115,4 @@ void options_read(const char *path);
void options_write(const char *path);
void options_dump(void);
struct tree *options_load_tree(const char *filename);
bool options_save_tree(struct tree *tree, const char *filename,
const char *page_title);
#endif

276
desktop/sslcert.c Normal file
View File

@ -0,0 +1,276 @@
/*
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* SSL Certificate verification UI (implementation)
*/
#include "utils/config.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include "content/content.h"
#include "content/fetch.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/sslcert.h"
#include "desktop/tree.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
/** Flags for each type of ssl tree node. */
enum tree_element_ssl {
TREE_ELEMENT_SSL_VERSION = 0x01,
TREE_ELEMENT_SSL_VALID_FROM = 0x02,
TREE_ELEMENT_SSL_VALID_TO = 0x03,
TREE_ELEMENT_SSL_CERT_TYPE = 0x04,
TREE_ELEMENT_SSL_SERIAL = 0x05,
TREE_ELEMENT_SSL_ISSUER = 0x06,
};
/** ssl certificate verification context. */
struct sslcert_session_data {
unsigned long num; /**< The number of ssl certificates in the chain */
char *url; /**< The url of the certificate */
struct tree *tree; /**< The root of the treeview */
llcache_query_response cb; /**< callback when cert is accepted or rejected */
void *cbpw; /**< context passed to callback */
};
/** Handle for the window icon. */
static hlcache_handle *sslcert_icon;
/** Initialise ssl certificate window. */
void sslcert_init(void)
{
sslcert_icon = tree_load_icon(tree_content_icon_name);
}
/**
* Get flags with which the sslcert tree should be created;
*
* \return the flags
*/
unsigned int sslcert_get_tree_flags(void)
{
return TREE_NO_DRAGS | TREE_NO_SELECT;
}
void sslcert_cleanup(void)
{
return;
}
struct sslcert_session_data *
sslcert_create_session_data(unsigned long num,
const char *url,
llcache_query_response cb,
void *cbpw)
{
struct sslcert_session_data *data;
data = malloc(sizeof(struct sslcert_session_data));
if (data == NULL) {
warn_user("NoMemory", 0);
return NULL;
}
data->url = strdup(url);
if (data->url == NULL) {
free(data);
warn_user("NoMemory", 0);
return NULL;
}
data->num = num;
data->cb = cb;
data->cbpw = cbpw;
return data;
}
static node_callback_resp sslcert_node_callback(void *user_data,
struct node_msg_data *msg_data)
{
if (msg_data->msg == NODE_DELETE_ELEMENT_IMG)
return NODE_CALLBACK_HANDLED;
return NODE_CALLBACK_NOT_HANDLED;
}
static struct node *sslcert_create_node(const struct ssl_cert_info *cert)
{
struct node *node;
struct node_element *element;
char *text;
text = messages_get_buff("SSL_Certificate_Subject", cert->subject);
if (text == NULL)
return NULL;
node = tree_create_leaf_node(NULL, NULL, text, false, false, false);
if (node == NULL) {
free(text);
return NULL;
}
tree_set_node_user_callback(node, sslcert_node_callback, NULL);
/* add issuer node */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_ISSUER, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_Issuer", cert->issuer);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* add version node */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_VERSION, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_Version", cert->version);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* add valid from node */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_VALID_FROM, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_ValidFrom", cert->not_before);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* add valid to node */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_VALID_TO, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_ValidTo", cert->not_after);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* add certificate type */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_CERT_TYPE, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_Type", cert->cert_type);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* add serial node */
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_SSL_SERIAL, false);
if (element != NULL) {
text = messages_get_buff("SSL_Certificate_Serial", cert->serial);
if (text == NULL) {
tree_delete_node(NULL, node, false);
return NULL;
}
tree_update_node_element(NULL, element, text, NULL);
}
/* set the display icon */
tree_set_node_icon(NULL, node, sslcert_icon);
return node;
}
bool sslcert_load_tree(struct tree *tree,
const struct ssl_cert_info *certs,
struct sslcert_session_data *data)
{
struct node *tree_root;
struct node *node;
unsigned long cert_loop;
assert(data != NULL && certs != NULL && tree != NULL);
tree_root = tree_get_root(tree);
for (cert_loop = 0; cert_loop < data->num; cert_loop++) {
node = sslcert_create_node(&(certs[cert_loop]));
if (node != NULL) {
/* There is no problem creating the node
* add an entry for it in the root of the
* treeview .
*/
tree_link_node(tree, tree_root, node, false);
}
}
data->tree = tree;
return tree;
}
static void sslcert_cleanup_session(struct sslcert_session_data *session)
{
assert(session != NULL);
free(session->url);
free(session);
}
bool sslcert_reject(struct sslcert_session_data *session)
{
session->cb(false, session->cbpw);
sslcert_cleanup_session(session);
return true;
}
/**
* Handle acceptance of certificate
*/
bool sslcert_accept(struct sslcert_session_data *session)
{
assert(session != NULL);
urldb_set_cert_permissions(session->url, true);
session->cb(true, session->cbpw);
sslcert_cleanup_session(session);
return true;
}

43
desktop/sslcert.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NETSURF_DESKTOP_SSLCERT_H_
#define _NETSURF_DESKTOP_SSLCERT_H_
#include <stdbool.h>
#include "desktop/tree.h"
struct sslcert_session_data;
void sslcert_init(void);
unsigned int sslcert_get_tree_flags(void);
void sslcert_cleanup(void);
struct sslcert_session_data *sslcert_create_session_data(unsigned long num,
const char *url, llcache_query_response cb, void *cbpw);
bool sslcert_load_tree(struct tree *tree,
const struct ssl_cert_info *certs,
struct sslcert_session_data *data);
bool sslcert_reject(struct sslcert_session_data *session);
bool sslcert_accept(struct sslcert_session_data *session);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -26,157 +27,167 @@
#include <stdbool.h>
#include <stdint.h>
struct url_data;
struct cookie_data;
#include "desktop/browser.h"
#include "image/bitmap.h"
struct hlcache_handle;
/* Tree flags */
enum tree_flags {
TREE_NO_FLAGS = 0,
TREE_NO_DRAGS = 1,
TREE_NO_FURNITURE = 2,
TREE_SINGLE_SELECT = 4,
TREE_NO_SELECT = 8,
TREE_MOVABLE = 16,
TREE_DELETE_EMPTY_DIRS = 32, /**< if the last child of a
* directory is deleted the
* directory will be deleted
* too.
*/
};
/** A "flag" value to indicate the element data contains title
* text. This value should be the first node_element in every
* node. All other values should be different than this one. The term
* flag is misused as it is actually a value used by the API consumer
* to indicate teh type of data a node element contains.
*/
#define TREE_ELEMENT_TITLE 0x00
/* these should be defined in front end code */
extern const char tree_directory_icon_name[];
extern const char tree_content_icon_name[];
struct tree;
struct node;
struct node_element;
typedef enum {
TREE_ELEMENT_URL,
TREE_ELEMENT_ADDED,
TREE_ELEMENT_LAST_VISIT,
TREE_ELEMENT_VISITS,
TREE_ELEMENT_VISITED,
TREE_ELEMENT_THUMBNAIL,
TREE_ELEMENT_TITLE,
TREE_ELEMENT_NAME,
TREE_ELEMENT_VALUE,
TREE_ELEMENT_COMMENT,
TREE_ELEMENT_DOMAIN,
TREE_ELEMENT_PATH,
TREE_ELEMENT_EXPIRES,
TREE_ELEMENT_LAST_USED,
TREE_ELEMENT_SECURE,
TREE_ELEMENT_VERSION,
TREE_ELEMENT_PERSISTENT,
TREE_ELEMENT_SSL
} node_element_data;
#define NODE_INSTEP 40
struct node_sprite;
struct toolbar;
typedef enum {
NODE_ELEMENT_TEXT, /* <-- Text only */
NODE_ELEMENT_TEXT_PLUS_SPRITE, /* <-- Text and sprite */
NODE_ELEMENT_THUMBNAIL, /* <-- Bitmap only */
NODE_ELEMENT_TEXT, /**< Text only */
NODE_ELEMENT_TEXT_PLUS_ICON, /**< Text and icon */
NODE_ELEMENT_BITMAP /**< Bitmap only */
} node_element_type;
typedef enum {
NODE_DELETE_ELEMENT_TXT, /**< The text of an element of the
* node is being deleted */
NODE_DELETE_ELEMENT_IMG, /**< The bitmap or icon of a node is
* being deleted */
NODE_LAUNCH, /**< The node has been launched */
NODE_ELEMENT_EDIT_FINISHING, /**< New text has to be accepted
* or rejected. */
NODE_ELEMENT_EDIT_FINISHED /**< Editing of a node_element has
* been finished. */
} node_msg;
struct node_element_box {
int x; /* <-- X offset from origin */
int y; /* <-- Y offset from origin */
int width; /* <-- Element width */
int height; /* <-- Element height */
typedef enum {
NODE_CALLBACK_HANDLED,
NODE_CALLBACK_NOT_HANDLED,
NODE_CALLBACK_REJECT, /**< reject new text for node element
* and leave editing mode. */
NODE_CALLBACK_CONTINUE /**< don't leave editig mode. */
} node_callback_resp;
/** Internal node message. */
struct node_msg_data {
node_msg msg; /**< The type of message. */
unsigned int flag; /**< message flags. */
struct node *node; /**< tree node messsage concerns. */
union {
char *text; /**< textural data. */
void *bitmap; /**< bitmap data. */
} data; /**< The message data. */
};
struct node_element {
struct node *parent; /* <-- Parent node */
node_element_type type; /* <-- Element type */
struct node_element_box box; /* <-- Element bounding box */
const char *text; /* <-- Text for the element */
struct node_sprite *sprite; /* <-- Sprite for the element */
struct node_element *next; /* <-- Next node element */
node_element_data data; /* <-- Data being represented */
};
struct node {
bool selected; /* <-- Whether the node is selected */
bool expanded; /* <-- Whether the node is expanded */
bool folder; /* <-- Whether the node is a folder */
bool editable; /* <-- Whether the node is editable */
bool retain_in_memory; /* <-- Whether the node remains in memory after deletion */
bool deleted; /* <-- Whether the node is currently deleted */
bool processing; /* <-- Internal flag used when moving */
struct node_element_box box; /* <-- Bounding box of all elements */
struct node_element data; /* <-- Data to display */
struct node *parent; /* <-- Parent entry (NULL for root) */
struct node *child; /* <-- First child */
struct node *last_child; /* <-- Last child */
struct node *previous; /* <-- Previous child of the parent */
struct node *next; /* <-- Next child of the parent */
};
struct tree {
unsigned int handle; /* <-- User assigned handle */
int offset_x; /* <-- User assigned tree x offset */
int offset_y; /* <-- User assigned tree y offset */
struct node *root; /* <-- Tree root element */
int width; /* <-- Tree width */
int height; /* <-- Tree height */
int window_width; /* <-- Tree window width */
int window_height; /* <-- Tree window height */
bool no_drag; /* <-- Tree items can't be dragged out */
bool no_vscroll; /* <-- Tree has a vertical scroll only when needed */
bool no_furniture; /* <-- Tree does not have connecting lines */
bool single_selection; /* <-- There can only be one item selected */
int edit_handle; /* <-- Handle for editing information */
uintptr_t textarea_handle; /* <-- Handle for UTF-8 textarea */
bool movable; /* <-- Whether nodes can be moved */
struct node_element *editing; /* <-- Node element being edited */
struct node *temp_selection; /* <-- Temporarily selected node */
struct toolbar *toolbar; /* <-- Tree toolbar */
/** callbacks to perform necessary operations on treeview. */
struct treeview_table {
void (*redraw_request)(int x, int y, int width, int height,
void *data); /**< request a redraw. */
void (*resized)(struct tree *tree, int width, int height,
void *data); /**< resize treeview area. */
void (*scroll_visible)(int y, int height, void *data); /**< scroll visible treeview area. */
void (*get_window_dimensions)(int *width, int *height, void *data); /**< get dimensions of window */
};
/**
* Informs the client about any events requiring his action
*
* \param user_data the user data which was passed at tree creation
* \param msg_data structure containing all the message information
* \return the appropriate node_callback_resp response
*/
typedef node_callback_resp (*tree_node_user_callback)(void *user_data,
struct node_msg_data *msg_data);
/* Non-platform specific code */
void tree_initialise(struct tree *tree);
void tree_initialise_nodes(struct tree *tree, struct node *root);
void tree_handle_node_changed(struct tree *tree, struct node *node,
bool recalculate_sizes, bool expansion);
void tree_handle_node_element_changed(struct tree *tree,
struct node_element *element);
void tree_recalculate_node(struct tree *tree, struct node *node, bool recalculate_sizes);
void tree_recalculate_node_positions(struct tree *tree, struct node *root);
struct node *tree_get_node_at(struct node *root, int x, int y, bool *furniture);
struct node_element *tree_get_node_element_at(struct node *node, int x, int y,
bool *furniture);
struct node_element *tree_find_element(struct node *node, node_element_data data);
void tree_move_selected_nodes(struct tree *tree, struct node *destination,
/* Functions for creating/deleting tree primitives and for tree structure
manipulation */
struct tree *tree_create(unsigned int flags,
const struct treeview_table *callbacks,
void *client_data);
struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
const char *title, bool editable, bool retain_in_memory,
bool deleted);
struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
const char *title, bool editable, bool retain_in_memory,
bool deleted);
struct node_element *tree_create_node_element(struct node *parent,
node_element_type type, unsigned int flag, bool editable);
void tree_link_node(struct tree *tree, struct node *link, struct node *node,
bool before);
bool tree_has_selection(struct node *node);
void tree_draw(struct tree *tree, int clip_x, int clip_y, int clip_width,
int clip_height);
void tree_link_node(struct node *link, struct node *node, bool before);
void tree_delink_node(struct node *node);
struct node *tree_create_folder_node(struct node *parent, const char *title);
struct node *tree_create_leaf_node(struct node *parent, const char *title);
struct node *tree_create_URL_node(struct node *parent,
const char *url, const struct url_data *data,
const char *title);
struct node *tree_create_URL_node_shared(struct node *parent,
const char *url, const struct url_data *data);
struct node *tree_create_cookie_node(struct node *parent,
const struct cookie_data *data);
void tree_set_node_sprite(struct node *node, const char *sprite,
const char *expanded);
void tree_set_node_expanded(struct tree *tree, struct node *node, bool expanded);
void tree_set_node_selected(struct tree *tree, struct node *node,
bool selected);
void tree_handle_selection_area(struct tree *tree, int x, int y, int width,
int height, bool invert);
void tree_delete_selected_nodes(struct tree *tree, struct node *node);
void tree_delink_node(struct tree *tree, struct node *node);
void tree_delete(struct tree *tree);
void tree_delete_node(struct tree *tree, struct node *node, bool siblings);
void tree_recalculate_size(struct tree *tree);
bool tree_handle_expansion(struct tree *tree, struct node *node, bool expanded,
/* setters and getters for properties and data */
void tree_set_node_icon(struct tree *tree, struct node *node,
struct hlcache_handle *icon);
void tree_set_node_expanded(struct tree *tree, struct node *node, bool expanded,
bool folder, bool leaf);
void tree_set_node_selected(struct tree *tree, struct node *node, bool all,
bool selected);
void tree_set_node_sort_function(struct tree *tree, struct node *node,
int (*sort) (struct node *, struct node *));
void tree_set_node_user_callback(struct node *node,
tree_node_user_callback callback, void *data);
void tree_set_redraw(struct tree *tree, bool redraw);
bool tree_get_redraw(struct tree *tree);
bool tree_node_has_selection(struct node *node);
bool tree_node_is_deleted(struct node *node);
bool tree_node_is_folder(struct node *node);
void tree_update_node_element(struct tree *tree, struct node_element *element,
const char *text, void *bitmap);
bool tree_update_element_text(struct tree *tree, struct node_element *element, char *text);
const char *tree_node_element_get_text(struct node_element *element);
struct node *tree_get_root(struct tree *tree);
bool tree_is_edited(struct tree *tree);
/* functions for traversing the tree */
struct node *tree_node_get_child(struct node *node);
struct node *tree_node_get_next(struct node *node);
void tree_draw(struct tree *tree, int x, int y,
int clip_x, int clip_y, int clip_width, int clip_height);
struct node_element *tree_node_find_element(struct node *node,
unsigned int flag, struct node_element *after);
void tree_delete_selected_nodes(struct tree *tree, struct node *node);
struct node *tree_get_selected_node(struct node *node);
struct node *tree_get_link_details(struct tree *tree, int x, int y,
bool *before);
void tree_launch_selected(struct tree *tree);
/* Platform specific code */
void tree_initialise_redraw(struct tree *tree);
void tree_redraw_area(struct tree *tree, int x, int y, int width, int height);
void tree_draw_line(int x, int y, int width, int height);
void tree_draw_node_element(struct tree *tree, struct node_element *element);
void tree_draw_node_expansion(struct tree *tree, struct node *node);
void tree_recalculate_node_element(struct node_element *element);
void tree_update_URL_node(struct node *node, const char *url,
const struct url_data *data);
void tree_resized(struct tree *tree);
void tree_set_node_sprite_folder(struct node *node);
bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse,
int x, int y);
void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0,
int x1, int y1);
bool tree_keypress(struct tree *tree, uint32_t key);
int tree_alphabetical_sort(struct node *, struct node *);
void tree_start_edit(struct tree *tree, struct node_element *element);
struct hlcache_handle *tree_load_icon(const char *name);
#endif

846
desktop/tree_url_node.c Normal file
View File

@ -0,0 +1,846 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Creation of URL nodes with use of trees (implementation)
*/
#include <assert.h>
#include <ctype.h>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/options.h"
#include "desktop/tree_url_node.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/url.h"
#include "utils/utils.h"
/** Flags for each type of url tree node. */
enum tree_element_url {
TREE_ELEMENT_URL = 0x01,
TREE_ELEMENT_LAST_VISIT = 0x02,
TREE_ELEMENT_VISITS = 0x03,
TREE_ELEMENT_THUMBNAIL = 0x04,
};
#define MAX_ICON_NAME_LEN 256
static bool initialised = false;
static hlcache_handle *folder_icon;
struct icon_entry {
content_type type;
hlcache_handle *icon;
};
struct icon_entry icon_table[] = {
{CONTENT_HTML, NULL},
{CONTENT_TEXTPLAIN, NULL},
{CONTENT_CSS, NULL},
#if defined(WITH_MNG) || defined(WITH_PNG)
{CONTENT_PNG, NULL},
#endif
#ifdef WITH_MNG
{CONTENT_JNG, NULL},
{CONTENT_MNG, NULL},
#endif
#ifdef WITH_JPEG
{CONTENT_JPEG, NULL},
#endif
#ifdef WITH_GIF
{CONTENT_GIF, NULL},
#endif
#ifdef WITH_BMP
{CONTENT_BMP, NULL},
{CONTENT_ICO, NULL},
#endif
#ifdef WITH_SPRITE
{CONTENT_SPRITE, NULL},
#endif
#ifdef WITH_DRAW
{CONTENT_DRAW, NULL},
#endif
#ifdef WITH_ARTWORKS
{CONTENT_ARTWORKS, NULL},
#endif
#ifdef WITH_NS_SVG
{CONTENT_SVG, NULL},
#endif
{CONTENT_UNKNOWN, NULL},
/* this serves as a sentinel */
{CONTENT_HTML, NULL}
};
void tree_url_node_init(void)
{
struct icon_entry *entry;
char icon_name[MAX_ICON_NAME_LEN];
if (initialised || option_tree_icons_dir == NULL)
return;
initialised = true;
folder_icon = tree_load_icon(tree_directory_icon_name);
entry = icon_table;
do {
tree_icon_name_from_content_type(icon_name, entry->type);
entry->icon = tree_load_icon(icon_name);
++entry;
} while (entry->type != CONTENT_HTML);
}
/**
* Creates a tree entry for a URL, and links it into the tree
*
* \param parent the node to link to
* \param url the URL (copied)
* \param data the URL data to use
* \param title the custom title to use
* \return the node created, or NULL for failure
*/
struct node *tree_create_URL_node(struct tree *tree, struct node *parent,
const char *url, const char *title,
tree_node_user_callback user_callback, void *callback_data)
{
struct node *node;
struct node_element *element;
char *text_cp, *squashed;
squashed = squash_whitespace(title ? title : url);
text_cp = strdup(squashed);
if (text_cp == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NULL;
}
free(squashed);
node = tree_create_leaf_node(tree, parent, text_cp, true, false,
false);
if (node == NULL) {
free(text_cp);
return NULL;
}
if (user_callback != NULL)
tree_set_node_user_callback(node, user_callback,
callback_data);
tree_create_node_element(node, NODE_ELEMENT_BITMAP,
TREE_ELEMENT_THUMBNAIL, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT, TREE_ELEMENT_VISITS,
false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_LAST_VISIT, false);
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_URL, true);
if (element != NULL) {
text_cp = strdup(url);
if (text_cp == NULL) {
tree_delete_node(tree, node, false);
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NULL;
}
tree_update_node_element(tree, element, text_cp, NULL);
}
return node;
}
/**
* Creates a tree entry for a URL, and links it into the tree.
*
* All information is used directly from the url_data, and as such cannot be
* edited and should never be freed.
*
* \param parent the node to link to
* \param url the URL
* \param data the URL data to use
* \return the node created, or NULL for failure
*/
struct node *tree_create_URL_node_shared(struct tree *tree, struct node *parent,
const char *url, const struct url_data *data,
tree_node_user_callback user_callback, void *callback_data)
{
struct node *node;
struct node_element *element;
const char *title;
assert(url && data);
if (data->title != NULL) {
title = data->title;
} else {
title = url;
}
node = tree_create_leaf_node(tree, parent, title, false, false, false);
if (node == NULL)
return NULL;
if (user_callback != NULL) {
tree_set_node_user_callback(node, user_callback,
callback_data);
}
tree_create_node_element(node, NODE_ELEMENT_BITMAP,
TREE_ELEMENT_THUMBNAIL, false);
tree_create_node_element(node, NODE_ELEMENT_TEXT, TREE_ELEMENT_VISITS,
false);
tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_LAST_VISIT, false);
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
TREE_ELEMENT_URL, false);
if (element != NULL) {
tree_update_node_element(tree, element, url, NULL);
}
tree_update_URL_node(tree, node, url, data, true);
return node;
}
/**
* Updates the node details for a URL node.
*
* \param node the node to update
*/
void tree_update_URL_node(struct tree *tree, struct node *node,
const char *url, const struct url_data *data, bool shared)
{
struct node_element *element;
struct bitmap *bitmap = NULL;
struct icon_entry *entry;
char *text_cp;
assert(node != NULL);
element = tree_node_find_element(node, TREE_ELEMENT_URL, NULL);
if (element == NULL)
return;
if (data != NULL) {
if (data->title == NULL)
urldb_set_url_title(url, url);
if (data->title == NULL)
return;
element = tree_node_find_element(node, TREE_ELEMENT_TITLE,
NULL);
if (shared)
tree_update_node_element(tree, element, data->title,
NULL);
else {
text_cp = strdup(data->title);
if (text_cp == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return;
}
tree_update_node_element(tree, element, text_cp, NULL);
}
} else {
data = urldb_get_url_data(url);
if (data == NULL)
return;
}
entry = icon_table;
do {
if (entry->type == data->type) {
if (entry->icon != NULL)
tree_set_node_icon(tree, node, entry->icon);
break;
}
++entry;
} while (entry->type != CONTENT_HTML);
/* update last visit text */
element = tree_node_find_element(node, TREE_ELEMENT_LAST_VISIT, element);
tree_update_element_text(tree,
element,
messages_get_buff("TreeLast",
(data->last_visit > 0) ?
ctime((time_t *)&data->last_visit) :
messages_get("TreeUnknown")));
/* update number of visits text */
element = tree_node_find_element(node, TREE_ELEMENT_VISITS, element);
tree_update_element_text(tree,
element,
messages_get_buff("TreeVisits", data->visits));
/* update thumbnail */
element = tree_node_find_element(node, TREE_ELEMENT_THUMBNAIL, element);
if (element != NULL) {
bitmap = urldb_get_thumbnail(url);
if (bitmap != NULL) {
tree_update_node_element(tree, element, NULL, bitmap);
}
}
}
const char *tree_url_node_get_title(struct node *node)
{
struct node_element *element;
element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
if (element == NULL)
return NULL;
return tree_node_element_get_text(element);
}
const char *tree_url_node_get_url(struct node *node)
{
struct node_element *element;
element = tree_node_find_element(node, TREE_ELEMENT_URL, NULL);
if (element == NULL)
return NULL;
return tree_node_element_get_text(element);
}
void tree_url_node_edit_title(struct tree *tree, struct node *node)
{
struct node_element *element;
element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL);
tree_start_edit(tree, element);
}
void tree_url_node_edit_url(struct tree *tree, struct node *node)
{
struct node_element *element;
element = tree_node_find_element(node, TREE_ELEMENT_URL, NULL);
tree_start_edit(tree, element);
}
node_callback_resp tree_url_node_callback(void *user_data,
struct node_msg_data *msg_data)
{
struct tree *tree;
struct node_element *element;
url_func_result res;
const char *text;
char *norm_text, *escaped_text;
const struct url_data *data;
/** @todo memory leaks on non-shared folder deletion. */
switch (msg_data->msg) {
case NODE_DELETE_ELEMENT_TXT:
switch (msg_data->flag) {
/* only history is using non-editable url
* elements so only history deletion will run
* this code
*/
case TREE_ELEMENT_URL:
/* reset URL characteristics */
urldb_reset_url_visit_data(
msg_data->data.text);
return NODE_CALLBACK_HANDLED;
case TREE_ELEMENT_TITLE:
return NODE_CALLBACK_HANDLED;
}
break;
case NODE_DELETE_ELEMENT_IMG:
if (msg_data->flag == TREE_ELEMENT_THUMBNAIL ||
msg_data->flag == TREE_ELEMENT_TITLE)
return NODE_CALLBACK_HANDLED;
break;
case NODE_LAUNCH:
element = tree_node_find_element(msg_data->node,
TREE_ELEMENT_URL, NULL);
if (element != NULL) {
text = tree_node_element_get_text(element);
browser_window_create(text, NULL, 0,
true, false);
return NODE_CALLBACK_HANDLED;
}
break;
case NODE_ELEMENT_EDIT_FINISHING:
text = msg_data->data.text;
if (msg_data->flag == TREE_ELEMENT_URL) {
res = url_escape(text, 0, false, NULL,
&escaped_text);
if (res == URL_FUNC_OK)
res = url_normalize(escaped_text,
&norm_text);
if (res != URL_FUNC_OK) {
if (res == URL_FUNC_FAILED) {
warn_user("NoURLError", 0);
return NODE_CALLBACK_CONTINUE;
}
else {
warn_user("NoMemory", 0);
return NODE_CALLBACK_REJECT;
}
}
msg_data->data.text = norm_text;
data = urldb_get_url_data(norm_text);
if (data == NULL) {
urldb_add_url(norm_text);
urldb_set_url_persistence(norm_text,
true);
data = urldb_get_url_data(norm_text);
if (data == NULL)
return NODE_CALLBACK_REJECT;
}
tree = user_data;
tree_update_URL_node(tree, msg_data->node,
norm_text, NULL, false);
}
else if (msg_data->flag == TREE_ELEMENT_TITLE) {
while (isspace(*text))
text++;
norm_text = strdup(text);
if (norm_text == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NODE_CALLBACK_REJECT;
}
/* don't allow zero length entry text, return
false */
if (norm_text[0] == '\0') {
warn_user("NoNameError", 0);
msg_data->data.text = NULL;
return NODE_CALLBACK_CONTINUE;
}
msg_data->data.text = norm_text;
}
return NODE_CALLBACK_HANDLED;
default:
break;
}
return NODE_CALLBACK_NOT_HANDLED;
}
/**
* Search the children of an xmlNode for an element.
*
* \param node xmlNode to search children of, or 0
* \param name name of element to find
* \return first child of node which is an element and matches name, or
* 0 if not found or parameter node is 0
*/
static xmlNode *tree_url_find_xml_element(xmlNode *node, const char *name)
{
xmlNode *xmlnode;
if (node == NULL)
return NULL;
for (xmlnode = node->children;
xmlnode && !(xmlnode->type == XML_ELEMENT_NODE &&
strcmp((const char *) xmlnode->name, name) == 0);
xmlnode = xmlnode->next)
;
return xmlnode;
}
/**
* Parse an entry represented as a li.
*
* \param li xmlNode for parsed li
* \param directory directory to add this entry to
*/
static void tree_url_load_entry(xmlNode *li, struct tree *tree,
struct node *directory, tree_node_user_callback callback,
void *callback_data)
{
char *url = NULL, *url1 = NULL;
char *title = NULL;
struct node *entry;
xmlNode *xmlnode;
const struct url_data *data;
url_func_result res;
for (xmlnode = li->children; xmlnode; xmlnode = xmlnode->next) {
/* The li must contain an "a" element */
if (xmlnode->type == XML_ELEMENT_NODE &&
strcmp((const char *)xmlnode->name, "a") == 0) {
url1 = (char *)xmlGetProp(xmlnode, (const xmlChar *) "href");
title = (char *)xmlNodeGetContent(xmlnode);
}
}
if ((url1 == NULL) || (title == NULL)) {
warn_user("TreeLoadError", "(Missing <a> in <li> or "
"memory exhausted.)");
return;
}
/* We're loading external input.
* This may be garbage, so attempt to normalise
*/
res = url_normalize(url1, &url);
if (res != URL_FUNC_OK) {
LOG(("Failed normalising '%s'", url1));
if (res == URL_FUNC_NOMEM)
warn_user("NoMemory", NULL);
xmlFree(url1);
xmlFree(title);
return;
}
/* No longer need this */
xmlFree(url1);
data = urldb_get_url_data(url);
if (data == NULL) {
/* No entry in database, so add one */
urldb_add_url(url);
/* now attempt to get url data */
data = urldb_get_url_data(url);
}
if (data == NULL) {
xmlFree(title);
free(url);
return;
}
/* Make this URL persistent */
urldb_set_url_persistence(url, true);
if (data->title == NULL)
urldb_set_url_title(url, title);
entry = tree_create_URL_node(tree, directory, url, title,
callback, callback_data);
if (entry == NULL) {
/** \todo why isn't this fatal? */
warn_user("NoMemory", 0);
} else {
tree_update_URL_node(tree, entry, url, data, false);
}
xmlFree(title);
free(url);
}
/**
* Parse a directory represented as a ul.
*
* \param ul xmlNode for parsed ul
* \param directory directory to add this directory to
*/
static void tree_url_load_directory(xmlNode *ul, struct tree *tree,
struct node *directory, tree_node_user_callback callback,
void *callback_data)
{
char *title;
struct node *dir;
xmlNode *xmlnode;
assert(ul != NULL);
assert(directory != NULL);
for (xmlnode = ul->children; xmlnode; xmlnode = xmlnode->next) {
/* The ul may contain entries as a li, or directories as
* an h4 followed by a ul. Non-element nodes may be present
* (eg. text, comments), and are ignored. */
if (xmlnode->type != XML_ELEMENT_NODE)
continue;
if (strcmp((const char *)xmlnode->name, "li") == 0) {
/* entry */
tree_url_load_entry(xmlnode, tree, directory, callback,
callback_data);
} else if (strcmp((const char *)xmlnode->name, "h4") == 0) {
/* directory */
title = (char *) xmlNodeGetContent(xmlnode );
if (!title) {
warn_user("TreeLoadError", "(Empty <h4> "
"or memory exhausted.)");
return;
}
for (xmlnode = xmlnode->next;
xmlnode && xmlnode->type != XML_ELEMENT_NODE;
xmlnode = xmlnode->next)
;
if ((xmlnode == NULL) ||
strcmp((const char *)xmlnode->name, "ul") != 0) {
/* next element isn't expected ul */
free(title);
warn_user("TreeLoadError", "(Expected "
"<ul> not present.)");
return;
}
dir = tree_create_folder_node(tree, directory, title,
true, false, false);
if (dir == NULL) {
free(title);
return;
}
if (callback != NULL)
tree_set_node_user_callback(dir, callback,
callback_data);
if (folder_icon != NULL)
tree_set_node_icon(tree, dir, folder_icon);
tree_url_load_directory(xmlnode, tree, dir, callback,
callback_data);
}
}
}
/**
* Loads an url tree from a specified file.
*
* \param filename name of file to read
* \param tree empty tree which data will be read into
* \return the file represented as a tree, or NULL on failure
*/
bool tree_urlfile_load(const char *filename, struct tree *tree,
tree_node_user_callback callback, void *callback_data)
{
xmlDoc *doc;
xmlNode *html, *body, *ul;
struct node *root;
FILE *fp = NULL;
if (filename == NULL) {
return false;
}
fp = fopen(filename, "r");
if (fp == NULL) {
return false;
}
fclose(fp);
doc = htmlParseFile(filename, "iso-8859-1");
if (doc == NULL) {
warn_user("TreeLoadError", messages_get("ParsingFail"));
return false;
}
html = tree_url_find_xml_element((xmlNode *) doc, "html");
body = tree_url_find_xml_element(html, "body");
ul = tree_url_find_xml_element(body, "ul");
if (ul == NULL) {
xmlFreeDoc(doc);
warn_user("TreeLoadError",
"(<html>...<body>...<ul> not found.)");
return false;
}
root = tree_get_root(tree);
tree_url_load_directory(ul, tree, root, callback, callback_data);
tree_set_node_expanded(tree, root, true, false, false);
xmlFreeDoc(doc);
return true;
}
/**
* Add an entry to the HTML tree for saving.
*
* The node must contain a sequence of node_elements in the following order:
*
* \param entry hotlist entry to add
* \param node node to add li to
* \return true on success, false on memory exhaustion
*/
static bool tree_url_save_entry(struct node *entry, xmlNode *node)
{
xmlNode *li, *a;
xmlAttr *href;
const char *text;
li = xmlNewChild(node, NULL, (const xmlChar *) "li", NULL);
if (li == NULL)
return false;
text = tree_url_node_get_title(entry);
if (text == NULL)
return false;
a = xmlNewTextChild(li, NULL, (const xmlChar *) "a",
(const xmlChar *) text);
if (a == NULL)
return false;
text = tree_url_node_get_url(entry);
if (text == NULL)
return false;
href = xmlNewProp(a, (const xmlChar *) "href", (const xmlChar *) text);
if (href == NULL)
return false;
return true;
}
/**
* Add a directory to the HTML tree for saving.
*
* \param directory hotlist directory to add
* \param node node to add ul to
* \return true on success, false on memory exhaustion
*/
static bool tree_url_save_directory(struct node *directory, xmlNode *node)
{
struct node *child;
xmlNode *ul, *h4;
const char *text;
ul = xmlNewChild(node, NULL, (const xmlChar *)"ul", NULL);
if (ul == NULL)
return false;
for (child = tree_node_get_child(directory); child;
child = tree_node_get_next(child)) {
if (!tree_node_is_folder(child)) {
/* entry */
if (!tree_url_save_entry(child, ul))
return false;
} else {
/* directory */
/* invalid HTML */
text = tree_url_node_get_title(child);
if (text == NULL)
return false;
h4 = xmlNewTextChild(ul, NULL,
(const xmlChar *) "h4",
(const xmlChar *) text);
if (h4 == NULL)
return false;
if (!tree_url_save_directory(child, ul))
return false;
} }
return true;
}
/**
* Perform a save to a specified file in the form of a html page
*
* \param filename the file to save to
* \param page_title title of the page
*/
bool tree_urlfile_save(struct tree *tree, const char *filename,
const char *page_title)
{
int res;
xmlDoc *doc;
xmlNode *html, *head, *title, *body;
/* Unfortunately the Browse Hotlist format is invalid HTML,
* so this is a lie.
*/
doc = htmlNewDoc(
(const xmlChar *) "http://www.w3.org/TR/html4/strict.dtd",
(const xmlChar *) "-//W3C//DTD HTML 4.01//EN");
if (doc == NULL) {
warn_user("NoMemory", 0);
return false;
}
html = xmlNewNode(NULL, (const xmlChar *) "html");
if (html == NULL) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
xmlDocSetRootElement(doc, html);
head = xmlNewChild(html, NULL, (const xmlChar *) "head", NULL);
if (head == NULL) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
title = xmlNewTextChild(head, NULL, (const xmlChar *) "title",
(const xmlChar *) page_title);
if (title == NULL) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
body = xmlNewChild(html, NULL, (const xmlChar *) "body", NULL);
if (body == NULL) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
if (!tree_url_save_directory(tree_get_root(tree), body)) {
warn_user("NoMemory", 0);
xmlFreeDoc(doc);
return false;
}
doc->charset = XML_CHAR_ENCODING_UTF8;
res = htmlSaveFileEnc(filename, doc, "iso-8859-1");
if (res == -1) {
warn_user("HotlistSaveError", 0);
xmlFreeDoc(doc);
return false;
}
xmlFreeDoc(doc);
return true;
}

56
desktop/tree_url_node.h Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Creation of URL nodes with use of trees public API
*/
#ifndef _NETSURF_DESKTOP_TREE_URL_NODE_H_
#define _NETSURF_DESKTOP_TREE_URL_NODE_H_
#include "desktop/tree.h"
void tree_url_node_init(void);
struct node *tree_create_URL_node(struct tree *tree,
struct node *parent, const char *url, const char *title,
tree_node_user_callback, void *callback_data);
struct node *tree_create_URL_node_shared(struct tree *tree,
struct node *parent, const char *url,
const struct url_data *data,
tree_node_user_callback, void *callback_data);
void tree_update_URL_node(struct tree *tree,struct node *node,
const char *url, const struct url_data *data, bool shared);
const char *tree_url_node_get_title(struct node *node);
const char *tree_url_node_get_url(struct node *node);
void tree_url_node_edit_title(struct tree *tree, struct node *node);
void tree_url_node_edit_url(struct tree *tree, struct node *node);
node_callback_resp tree_url_node_callback(void *user_data,
struct node_msg_data *msg_data);
bool tree_urlfile_load(const char *filename, struct tree *tree,
tree_node_user_callback, void *callback_data);
bool tree_urlfile_save(struct tree *tree, const char *filename,
const char *page_title);
/* front end specific */
void tree_icon_name_from_content_type(char *buffer, content_type type);
#endif

View File

@ -35,12 +35,6 @@ void die(const char *error)
exit(1);
}
bool cookies_update(const char *domain, const struct cookie_data *data)
{
return true;
}
/**
* Return the filename part of a full path
*

View File

@ -18,45 +18,56 @@
#include "desktop/tree.h"
void tree_initialise_redraw(struct tree *tree)
{
}
const char tree_directory_icon_name[] = "directory.png";
const char tree_content_icon_name[] = "content.png";
void tree_redraw_area(struct tree *tree, int x, int y, int width, int height)
{
}
void tree_draw_line(int x, int y, int width, int height)
{
}
void tree_draw_node_element(struct tree *tree, struct node_element *element)
{
}
void tree_draw_node_expansion(struct tree *tree, struct node *node)
/**
* Translates a content_type to the name of a respective icon
*
* \param content_type content type
* \param buffer buffer for the icon name
*/
void tree_icon_name_from_content_type(char *buffer, content_type type)
{
// TODO: design/acquire icons
switch (type) {
case CONTENT_HTML:
case CONTENT_TEXTPLAIN:
case CONTENT_CSS:
#if defined(WITH_MNG) || defined(WITH_PNG)
case CONTENT_PNG:
#endif
#ifdef WITH_MNG
case CONTENT_JNG:
case CONTENT_MNG:
#endif
#ifdef WITH_JPEG
case CONTENT_JPEG:
#endif
#ifdef WITH_GIF
case CONTENT_GIF:
#endif
#ifdef WITH_BMP
case CONTENT_BMP:
case CONTENT_ICO:
#endif
#ifdef WITH_SPRITE
case CONTENT_SPRITE:
#endif
#ifdef WITH_DRAW
case CONTENT_DRAW:
#endif
#ifdef WITH_ARTWORKS
case CONTENT_ARTWORKS:
#endif
#ifdef WITH_NS_SVG
case CONTENT_SVG:
#endif
default:
sprintf(buffer, tree_content_icon_name);
break;
}
}
void tree_recalculate_node_element(struct node_element *element)
{
}
void tree_update_URL_node(struct node *node, const char *url,
const struct url_data *data)
{
}
void tree_resized(struct tree *tree)
{
}
void tree_set_node_sprite_folder(struct node *node)
{
}
void tree_set_node_sprite(struct node *node, const char *sprite,
const char *expanded)
{
}

213
gtk/gtk_cookies.c Normal file
View File

@ -0,0 +1,213 @@
/*
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Cookies (implementation).
*/
#include "desktop/cookies.h"
#include "desktop/plotters.h"
#include "desktop/tree.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_cookies.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_scaffolding.h"
#include "gtk/gtk_treeview.h"
#define GLADE_NAME "cookies.glade"
#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
gpointer g)
struct menu_events {
const char *widget;
GCallback handler;
};
static void nsgtk_cookies_init_menu(void);
/* edit menu */
MENUPROTO(delete_selected);
MENUPROTO(delete_all);
MENUPROTO(select_all);
MENUPROTO(clear_selection);
/* view menu*/
MENUPROTO(expand_all);
MENUPROTO(expand_domains);
MENUPROTO(expand_cookies);
MENUPROTO(collapse_all);
MENUPROTO(collapse_domains);
MENUPROTO(collapse_cookies);
static struct menu_events menu_events[] = {
/* edit menu */
MENUEVENT(delete_selected),
MENUEVENT(delete_all),
MENUEVENT(select_all),
MENUEVENT(clear_selection),
/* view menu*/
MENUEVENT(expand_all),
MENUEVENT(expand_domains),
MENUEVENT(expand_cookies),
MENUEVENT(collapse_all),
MENUEVENT(collapse_domains),
MENUEVENT(collapse_cookies),
{NULL, NULL}
};
static struct nsgtk_treeview *cookies_window;
static GladeXML *gladeFile;
GtkWindow *wndCookies;
/**
* Creates the window for the cookies tree.
*/
void nsgtk_cookies_init(void)
{
gchar *glade_location = g_strconcat(res_dir_location, GLADE_NAME, NULL);
gladeFile = glade_xml_new(glade_location, NULL, NULL);
g_free(glade_location);
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
glade_xml_signal_autoconnect(gladeFile);
wndCookies = GTK_WINDOW(glade_xml_get_widget(gladeFile, "wndCookies"));
window = wndCookies;
scrolled = GTK_SCROLLED_WINDOW(glade_xml_get_widget(gladeFile,
"cookiesScrolled"));
drawing_area = GTK_DRAWING_AREA(glade_xml_get_widget(gladeFile,
"cookiesDrawingArea"));
cookies_window = nsgtk_treeview_create(cookies_get_tree_flags(), window,
scrolled, drawing_area);
if (cookies_window == NULL)
return;
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
CONNECT(window, "delete_event", gtk_widget_hide_on_delete, NULL);
CONNECT(window, "hide", nsgtk_tree_window_hide, cookies_window);
cookies_initialise(nsgtk_treeview_get_tree(cookies_window));
nsgtk_cookies_init_menu();
}
/**
* Connects menu events in the cookies window.
*/
void nsgtk_cookies_init_menu()
{
struct menu_events *event = menu_events;
while (event->widget != NULL)
{
GtkWidget *w = glade_xml_get_widget(gladeFile, event->widget);
g_signal_connect(G_OBJECT(w), "activate", event->handler,
cookies_window);
event++;
}
}
/**
* Destroys the cookies window and performs any other necessary cleanup actions.
*/
void nsgtk_cookies_destroy(void)
{
/* TODO: what about gladeFile? */
cookies_cleanup();
nsgtk_treeview_destroy(cookies_window);
}
/* edit menu */
MENUHANDLER(delete_selected)
{
cookies_delete_selected();
return TRUE;
}
MENUHANDLER(delete_all)
{
cookies_delete_all();
return TRUE;
}
MENUHANDLER(select_all)
{
cookies_select_all();
return TRUE;
}
MENUHANDLER(clear_selection)
{
cookies_clear_selection();
return TRUE;
}
/* view menu*/
MENUHANDLER(expand_all)
{
cookies_expand_all();
return TRUE;
}
MENUHANDLER(expand_domains)
{
cookies_expand_domains();
return TRUE;
}
MENUHANDLER(expand_cookies)
{
cookies_expand_cookies();
return TRUE;
}
MENUHANDLER(collapse_all)
{
cookies_collapse_all();
return TRUE;
}
MENUHANDLER(collapse_domains)
{
cookies_collapse_domains();
return TRUE;
}
MENUHANDLER(collapse_cookies)
{
cookies_collapse_cookies();
return TRUE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -16,8 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/browser.h"
/** \file
* Cookies (interface).
*/
void hotlist_visited(struct hlcache_handle *content)
{
}
#ifndef __NSGTK_COOKIES_H__
#define __NSGTK_COOKIES_H__
#include <gtk/gtk.h>
extern GtkWindow *wndCookies;
void nsgtk_cookies_init(void);
void nsgtk_cookies_destroy(void);
#endif /* __NSGTK_COOKIES_H__ */

View File

@ -49,20 +49,25 @@
#include "desktop/browser.h"
#include "desktop/cookies.h"
#include "desktop/gui.h"
#include "desktop/history_global_core.h"
#include "desktop/netsurf.h"
#include "desktop/options.h"
#include "desktop/save_pdf/pdf_plotters.h"
#include "desktop/searchweb.h"
#include "desktop/sslcert.h"
#include "desktop/textinput.h"
#include "gtk/gtk_gui.h"
#include "gtk/dialogs/gtk_options.h"
#include "gtk/gtk_completion.h"
#include "gtk/gtk_cookies.h"
#include "gtk/gtk_download.h"
#include "gtk/gtk_filetype.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_hotlist.h"
#include "gtk/gtk_throbber.h"
#include "gtk/gtk_treeview.h"
#include "gtk/gtk_window.h"
#include "gtk/options.h"
#include "gtk/gtk_throbber.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_filetype.h"
#include "gtk/gtk_download.h"
#include "gtk/gtk_schedule.h"
#include "render/box.h"
@ -101,7 +106,9 @@ static struct browser_window *select_menu_bw;
static struct form_control *select_menu_control;
static void nsgtk_ssl_accept(GtkButton *w, gpointer data);
static void nsgtk_ssl_reject(GtkButton *w, gpointer data);
static void nsgtk_ssl_reject(GtkWidget *w, gpointer data);
static gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event,
gpointer data);
static void nsgtk_select_menu_clicked(GtkCheckMenuItem *checkmenuitem,
gpointer user_data);
#ifdef WITH_PDF_EXPORT
@ -377,6 +384,24 @@ static void check_options(char **respath)
LOG(("Using '%s' as download directory", hdir));
option_downloads_directory = hdir;
}
if (!option_tree_icons_dir) {
sfindresourcedef(respath, buf, "icons/", "~/.netsurf/");
LOG(("Using '%s' as Tree icons dir", buf));
option_tree_icons_dir = strdup(buf);
}
if (!option_tree_icons_dir)
die("Failed initialising tree icons option");
if (!option_hotlist_path) {
sfindresourcedef(respath, buf, "Hotlist", "~/.netsurf/");
LOG(("Using '%s' as Hotlist file", buf));
option_hotlist_path = strdup(buf);
}
if (!option_hotlist_path)
die("Failed initialising hotlist option");
sfindresourcedef(respath, buf, "Print", "~/.netsurf/");
LOG(("Using '%s' as Print Settings file", buf));
@ -483,6 +508,10 @@ static void gui_init(int argc, char** argv, char **respath)
if (nsgtk_download_init() == false)
die("Unable to initialise download window.\n");
nsgtk_cookies_init();
nsgtk_hotlist_init();
sslcert_init();
if (option_homepage_url != NULL && option_homepage_url[0] != '\0')
addr = option_homepage_url;
@ -642,11 +671,16 @@ void gui_quit(void)
nsgtk_download_destroy();
urldb_save_cookies(option_cookie_jar);
urldb_save(option_url_file);
nsgtk_cookies_destroy();
nsgtk_history_destroy();
nsgtk_hotlist_destroy();
sslcert_cleanup();
free(default_stylesheet_url);
free(quirks_stylesheet_url);
free(adblock_stylesheet_url);
free(option_cookie_file);
free(option_cookie_jar);
free(option_tree_icons_dir);
free(print_options_file_location);
free(search_engines_file_location);
free(search_default_ico_location);
@ -744,73 +778,88 @@ void die(const char * const error)
}
void hotlist_visited(hlcache_handle *content)
{
}
void gui_cert_verify(const char *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
{
static struct nsgtk_treeview *ssl_window;
struct sslcert_session_data *data;
GladeXML *x = glade_xml_new(glade_ssl_file_location, NULL, NULL);
GtkWindow *wnd = GTK_WINDOW(glade_xml_get_widget(x, "wndSSLProblem"));
GtkButton *accept, *reject;
void **session = calloc(sizeof(void *), 5);
void **session = calloc(sizeof(void *), 3);
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
session[0] = strdup(url);
session[1] = cb;
session[2] = cbpw;
session[3] = x;
session[4] = wnd;
data = sslcert_create_session_data(num, url, cb, cbpw);
window = GTK_WINDOW(
glade_xml_get_widget(x,"wndSSLProblem"));
scrolled = GTK_SCROLLED_WINDOW(
glade_xml_get_widget(x,"SSLScrolled"));
drawing_area = GTK_DRAWING_AREA(
glade_xml_get_widget(x,"SSLDrawingArea"));
ssl_window = nsgtk_treeview_create(sslcert_get_tree_flags(),
window, scrolled, drawing_area);
if (ssl_window == NULL)
return;
sslcert_load_tree(nsgtk_treeview_get_tree(ssl_window), certs, data);
accept = GTK_BUTTON(glade_xml_get_widget(x, "sslaccept"));
reject = GTK_BUTTON(glade_xml_get_widget(x, "sslreject"));
reject = GTK_BUTTON(glade_xml_get_widget(x, "sslreject"));
g_signal_connect(G_OBJECT(accept), "clicked",
G_CALLBACK(nsgtk_ssl_accept), (gpointer)session);
g_signal_connect(G_OBJECT(reject), "clicked",
G_CALLBACK(nsgtk_ssl_reject), (gpointer)session);
gtk_widget_show(GTK_WIDGET(wnd));
session[0] = x;
session[1] = ssl_window;
session[2] = data;
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
CONNECT(accept, "clicked", nsgtk_ssl_accept, session);
CONNECT(reject, "clicked", nsgtk_ssl_reject, session);
CONNECT(window, "delete_event", G_CALLBACK(nsgtk_ssl_delete_event),
(gpointer)session);
gtk_widget_show(GTK_WIDGET(window));
}
void nsgtk_ssl_accept(GtkButton *w, gpointer data)
{
void **session = data;
char *url = session[0];
nserror (*cb)(bool proceed, void *pw) = session[1];
void *cbpw = session[2];
GladeXML *x = session[3];
GtkWindow *wnd = session[4];
GladeXML *x = session[0];
struct nsgtk_treeview *wnd = session[1];
struct sslcert_session_data *ssl_data = session[2];
urldb_set_cert_permissions(url, true);
cb(true, cbpw);
gtk_widget_destroy(GTK_WIDGET(wnd));
sslcert_accept(ssl_data);
nsgtk_treeview_destroy(wnd);
g_object_unref(G_OBJECT(x));
free(url);
free(session);
}
void nsgtk_ssl_reject(GtkButton *w, gpointer data)
void nsgtk_ssl_reject(GtkWidget *w, gpointer data)
{
void **session = data;
nserror (*cb)(bool proceed, void *pw) = session[1];
void *cbpw = session[2];
GladeXML *x = session[3];
GtkWindow *wnd = session[4];
GladeXML *x = session[0];
struct nsgtk_treeview *wnd = session[1];
struct sslcert_session_data *ssl_data = session[2];
cb(false, cbpw);
gtk_widget_destroy(GTK_WIDGET(wnd));
sslcert_reject(ssl_data);
nsgtk_treeview_destroy(wnd);
g_object_unref(G_OBJECT(x));
free(session[0]);
free(session);
}
gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event, gpointer data)
{
nsgtk_ssl_reject(w, data);
return FALSE;
}
utf8_convert_ret utf8_to_local_encoding(const char *string, size_t len,
char **result)
@ -883,12 +932,6 @@ char *url_to_path(const char *url)
return respath;
}
bool cookies_update(const char *domain, const struct cookie_data *data)
{
return true;
}
#ifdef WITH_PDF_EXPORT
void PDF_Password(char **owner_pass, char **user_pass, char *path)

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -16,612 +17,248 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include "desktop/history_global_core.h"
#include "desktop/plotters.h"
#include "desktop/tree.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_scaffolding.h"
#include "gtk/gtk_treeview.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "utils/url.h"
#include "utils/messages.h"
#include "content/urldb.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_window.h"
#include "gtk/gtk_bitmap.h"
enum
{
SITE_TITLE = 0,
SITE_DOMAIN,
SITE_ADDRESS,
SITE_LASTVISIT,
SITE_TOTALVISITS,
SITE_THUMBNAIL,
SITE_NCOLS
#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
gpointer g)
struct menu_events {
const char *widget;
GCallback handler;
};
enum
{
DOM_DOMAIN,
DOM_LASTVISIT,
DOM_TOTALVISITS,
DOM_HAS_SITES,
DOM_NCOLS
static void nsgtk_history_init_menu(void);
/* file menu*/
MENUPROTO(export);
/* edit menu */
MENUPROTO(delete_selected);
MENUPROTO(delete_all);
MENUPROTO(select_all);
MENUPROTO(clear_selection);
/* view menu*/
MENUPROTO(expand_all);
MENUPROTO(expand_directories);
MENUPROTO(expand_addresses);
MENUPROTO(collapse_all);
MENUPROTO(collapse_directories);
MENUPROTO(collapse_addresses);
MENUPROTO(launch);
static struct menu_events menu_events[] = {
/* file menu*/
MENUEVENT(export),
/* edit menu */
MENUEVENT(delete_selected),
MENUEVENT(delete_all),
MENUEVENT(select_all),
MENUEVENT(clear_selection),
/* view menu*/
MENUEVENT(expand_all),
MENUEVENT(expand_directories),
MENUEVENT(expand_addresses),
MENUEVENT(collapse_all),
MENUEVENT(collapse_directories),
MENUEVENT(collapse_addresses),
MENUEVENT(launch),
{NULL, NULL}
};
GtkWindow *wndHistory;
static struct nsgtk_treeview *global_history_window;
static GladeXML *gladeFile;
GtkWindow *wndHistory;
static const gchar* dateToday;
static const gchar* dateYesterday;
static const gchar* dateAt;
static const gchar* domainAll;
static struct history_model *history;
static void nsgtk_history_init_model(void);
static void nsgtk_history_init_filters(void);
static void nsgtk_history_init_sort(void);
static void nsgtk_history_init_treeviews(void);
static void nsgtk_history_init_list(void);
static bool nsgtk_history_add_internal(const char *, const struct url_data *);
static void nsgtk_history_show_domain(GtkTreeSelection *treesel,
GString *domain_filter);
static void nsgtk_history_show_all(void);
static gboolean nsgtk_history_filter_search(GtkTreeModel *model,
GtkTreeIter *iter, GtkWidget *search_entry);
static gboolean nsgtk_history_filter_sites(GtkTreeModel *model,
GtkTreeIter *iter, GString *domain_filter);
static gchar *nsgtk_history_parent_get(gchar *domain);
static void nsgtk_history_parent_update(gchar *path, const struct url_data *data);
static void nsgtk_history_domain_sort_changed(GtkComboBox *combo);
static gint nsgtk_history_domain_sort_compare(GtkTreeModel *model, GtkTreeIter *a,
GtkTreeIter *b, gint sort_column);
static void nsgtk_history_domain_set_visible (GtkTreeModel *model,
GtkTreePath *path, GtkTreeIter *iter, gboolean has_sites);
static void nsgtk_history_search(void);
static void nsgtk_history_search_clear (GtkEntry *entry);
static gchar *nsgtk_history_date_parse(time_t visit_time);
static void nsgtk_history_row_activated(GtkTreeView *, GtkTreePath *,
GtkTreeViewColumn *);
static void nsgtk_history_update_info(GtkTreeSelection *treesel,
gboolean domain);
static void nsgtk_history_scroll_top (GtkScrolledWindow *scrolled_window);
/**
* Creates the window for the global history tree.
*/
bool nsgtk_history_init(void)
{
dateToday = messages_get("DateToday");
dateYesterday = messages_get("DateYesterday");
dateAt = messages_get("DateAt");
domainAll = messages_get("DomainAll");
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
gladeFile = glade_xml_new(glade_history_file_location, NULL, NULL);
if (gladeFile == NULL)
return false;
glade_xml_signal_autoconnect(gladeFile);
wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeFile, "wndHistory"));
nsgtk_history_init_model();
nsgtk_history_init_list();
nsgtk_history_init_filters();
nsgtk_history_init_sort();
nsgtk_history_init_treeviews();
wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeFile, "wndHistory"));
window = wndHistory;
scrolled = GTK_SCROLLED_WINDOW(glade_xml_get_widget(gladeFile,
"globalHistoryScrolled"));
nsgtk_history_show_all();
drawing_area = GTK_DRAWING_AREA(glade_xml_get_widget(gladeFile,
"globalHistoryDrawingArea"));
return true;
}
global_history_window = nsgtk_treeview_create(
history_global_get_tree_flags(), window, scrolled,
drawing_area);
if (global_history_window == NULL)
return false;
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
CONNECT(window, "delete_event", gtk_widget_hide_on_delete, NULL);
CONNECT(window, "hide", nsgtk_tree_window_hide, global_history_window);
history_global_initialise(
nsgtk_treeview_get_tree(global_history_window));
nsgtk_history_init_menu();
void nsgtk_history_init_model(void)
{
history = malloc(sizeof(struct history_model));
history->history_list = gtk_list_store_new(SITE_NCOLS,
G_TYPE_STRING, /* title */
G_TYPE_STRING, /* domain */
G_TYPE_STRING, /* address */
G_TYPE_INT, /* last visit */
G_TYPE_INT, /* num visits */
G_TYPE_POINTER); /* thumbnail */
history->history_filter = gtk_tree_model_filter_new(
GTK_TREE_MODEL(history->history_list), NULL);
history->site_filter = gtk_tree_model_filter_new(
history->history_filter,NULL);
history->site_sort = gtk_tree_model_sort_new_with_model(history->site_filter);
history->site_treeview = GTK_TREE_VIEW(glade_xml_get_widget(gladeFile,
"treeHistory"));
history->site_selection =
gtk_tree_view_get_selection(history->site_treeview);
history->domain_list = gtk_list_store_new(DOM_NCOLS,
G_TYPE_STRING, /* domain */
G_TYPE_INT, /* last visit */
G_TYPE_INT, /* num visits */
G_TYPE_BOOLEAN); /* has sites */
history->domain_filter = gtk_tree_model_filter_new(
GTK_TREE_MODEL(history->domain_list), NULL);
history->domain_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
history->domain_sort = gtk_tree_model_sort_new_with_model(
history->domain_filter);
history->domain_treeview = GTK_TREE_VIEW(glade_xml_get_widget(
gladeFile,"treeDomain"));
history->domain_selection =
gtk_tree_view_get_selection(history->domain_treeview);
}
void nsgtk_history_init_list(void)
{
GtkTreeIter iter;
gtk_list_store_clear(history->history_list);
gtk_list_store_clear(history->domain_list);
gtk_list_store_append(history->domain_list, &iter);
gtk_list_store_set(history->domain_list, &iter,
DOM_DOMAIN, domainAll,
DOM_LASTVISIT, -2,
DOM_TOTALVISITS, -2,
DOM_HAS_SITES, TRUE,
-1);
urldb_iterate_entries(nsgtk_history_add_internal);
}
void nsgtk_history_init_filters(void)
{
GtkWidget *search_entry, *clear_button;
GString *filter_string = g_string_new(NULL);
search_entry = glade_xml_get_widget(gladeFile,"entrySearch");
clear_button = glade_xml_get_widget(gladeFile,"buttonClearSearch");
g_signal_connect(G_OBJECT(search_entry), "changed",
G_CALLBACK(nsgtk_history_search), NULL);
g_signal_connect_swapped(G_OBJECT(clear_button), "clicked",
G_CALLBACK(nsgtk_history_search_clear),
GTK_ENTRY(search_entry));
gtk_tree_model_filter_set_visible_func(
GTK_TREE_MODEL_FILTER(history->history_filter),
(GtkTreeModelFilterVisibleFunc)
nsgtk_history_filter_search, search_entry, NULL);
gtk_tree_model_filter_set_visible_func(
GTK_TREE_MODEL_FILTER(history->site_filter),
(GtkTreeModelFilterVisibleFunc)
nsgtk_history_filter_sites, filter_string, NULL);
gtk_tree_model_filter_set_visible_column(
GTK_TREE_MODEL_FILTER(history->domain_filter),
DOM_HAS_SITES);
g_signal_connect(G_OBJECT(history->site_selection), "changed",
G_CALLBACK(nsgtk_history_update_info), FALSE);
g_signal_connect(G_OBJECT(history->domain_selection), "changed",
G_CALLBACK(nsgtk_history_show_domain), filter_string);
}
void nsgtk_history_init_sort(void)
{
GtkWidget *domain_window = glade_xml_get_widget(gladeFile,
"windowDomain");
GtkComboBox *sort_combo_box =
GTK_COMBO_BOX(glade_xml_get_widget(
gladeFile, "comboSort"));
gtk_combo_box_set_active(sort_combo_box, 0);
g_signal_connect(G_OBJECT(sort_combo_box), "changed",
G_CALLBACK(nsgtk_history_domain_sort_changed), NULL);
g_signal_connect_swapped(G_OBJECT(sort_combo_box), "changed",
G_CALLBACK(nsgtk_history_scroll_top), domain_window);
gtk_tree_sortable_set_sort_func(
GTK_TREE_SORTABLE(history->domain_sort),
DOM_LASTVISIT, (GtkTreeIterCompareFunc)
nsgtk_history_domain_sort_compare,
GUINT_TO_POINTER(DOM_LASTVISIT), NULL);
gtk_tree_sortable_set_sort_func(
GTK_TREE_SORTABLE(history->domain_sort),
DOM_TOTALVISITS, (GtkTreeIterCompareFunc)
nsgtk_history_domain_sort_compare,
GUINT_TO_POINTER(DOM_TOTALVISITS), NULL);
gtk_tree_sortable_set_sort_func(
GTK_TREE_SORTABLE(history->site_sort),
SITE_LASTVISIT, (GtkTreeIterCompareFunc)
nsgtk_history_domain_sort_compare,
GUINT_TO_POINTER(SITE_LASTVISIT), NULL);
gtk_tree_sortable_set_sort_func(
GTK_TREE_SORTABLE(history->site_sort),
SITE_TOTALVISITS, (GtkTreeIterCompareFunc)
nsgtk_history_domain_sort_compare,
GUINT_TO_POINTER(SITE_TOTALVISITS), NULL);
}
void nsgtk_history_init_treeviews(void)
{
GtkCellRenderer *renderer;
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(history->site_treeview, -1,
messages_get("Title"), renderer,
"text", SITE_TITLE,
NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(history->domain_treeview,
-1, messages_get("Domain"), renderer,
"markup", DOM_DOMAIN,
NULL);
gtk_tree_view_set_model(history->site_treeview, history->site_sort);
gtk_tree_view_set_model(history->domain_treeview, history->domain_sort);
g_signal_connect(history->site_treeview, "row-activated",
G_CALLBACK(nsgtk_history_row_activated), NULL);
}
bool nsgtk_history_add_internal(const char *url, const struct url_data *data)
{
GtkTreeIter iter;
gchar *domain, *path;
if (url_host(url, &domain) != URL_FUNC_OK)
strcpy(domain, messages_get("gtkUnknownHost"));
if (data->visits > 0)
{
path = nsgtk_history_parent_get(domain);
nsgtk_history_parent_update(path, data);
gtk_list_store_append(history->history_list, &iter);
gtk_list_store_set(history->history_list, &iter,
SITE_TITLE, data->title ? data->title :
url,
SITE_DOMAIN, domain,
SITE_ADDRESS, url,
SITE_LASTVISIT, data->last_visit,
SITE_TOTALVISITS, data->visits,
SITE_THUMBNAIL,
gtk_bitmap_get_primary(
urldb_get_thumbnail(url)),
-1);
}
return true;
}
gchar *nsgtk_history_parent_get(gchar *domain)
/**
* Connects menu events in the global history window.
*/
void nsgtk_history_init_menu(void)
{
GtkTreeIter iter;
gchar *path;
/* Adds an extra entry in the list to act as the root domain
* (which will keep track of things like visits to all sites
* in the domain), This does not work as a tree because the
* children cannot be displayed if the root is hidden
* (which would conflict with the site view) */
path = g_hash_table_lookup(history->domain_hash, domain);
if (path == NULL){
gtk_list_store_append(history->domain_list, &iter);
gtk_list_store_set(history->domain_list, &iter,
DOM_DOMAIN, domain,
DOM_LASTVISIT, messages_get("gtkUnknownHost"),
DOM_TOTALVISITS, 0,
-1);
path = gtk_tree_model_get_string_from_iter(
GTK_TREE_MODEL(history->domain_list), &iter);
g_hash_table_insert(history->domain_hash, domain,
path);
}
struct menu_events *event = menu_events;
return path;
}
void nsgtk_history_parent_update(gchar *path, const struct url_data *data)
{
GtkTreeIter iter;
gint num_visits, last_visit;
gtk_tree_model_get_iter_from_string(
GTK_TREE_MODEL(history->domain_list), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(history->domain_list), &iter,
DOM_TOTALVISITS, &num_visits,
DOM_LASTVISIT, &last_visit,
-1);
gtk_list_store_set(history->domain_list, &iter,
DOM_TOTALVISITS, num_visits + data->visits,
DOM_LASTVISIT, max(last_visit,data->last_visit),
-1);
/* Handle "All" */
gtk_tree_model_get_iter_from_string(
GTK_TREE_MODEL(history->domain_list), &iter, "0");
gtk_tree_model_get(GTK_TREE_MODEL(history->domain_list), &iter,
DOM_TOTALVISITS, &num_visits,
DOM_LASTVISIT, &last_visit,
-1);
gtk_list_store_set(history->domain_list, &iter,
DOM_TOTALVISITS, num_visits + data->visits,
DOM_LASTVISIT, max(last_visit,data->last_visit),
-1);
}
void nsgtk_history_show_domain(GtkTreeSelection *treesel,
GString *domain_filter)
{
GtkTreeIter iter;
GtkTreeModel *model;
if (gtk_tree_selection_get_selected(treesel, &model, &iter)) {
gtk_tree_model_get(model, &iter, DOM_DOMAIN,
&domain_filter->str, -1);
gtk_tree_model_filter_refilter(
GTK_TREE_MODEL_FILTER(history->site_filter));
}
nsgtk_history_update_info(treesel, TRUE);
}
static void nsgtk_history_show_all(void)
{
GtkTreePath *path = gtk_tree_path_new_from_string("0");
gtk_tree_selection_select_path(history->domain_selection, path);
gtk_tree_path_free(path);
}
gboolean nsgtk_history_filter_search(GtkTreeModel *model, GtkTreeIter *iter,
GtkWidget *search_entry)
{
gchar *title, *address, *domain, *path;
gint result;
GtkTreeIter new_iter;
const gchar *search = gtk_entry_get_text(GTK_ENTRY(search_entry));
gtk_tree_model_get(model, iter, SITE_TITLE, &title,
SITE_ADDRESS, &address,
SITE_DOMAIN, &domain,
-1);
if (title)
result = (strstr(title, search) || strstr(address, search));
else
result = FALSE;
if (result) {
path = g_hash_table_lookup(history->domain_hash, domain);
gtk_tree_model_get_iter_from_string(
GTK_TREE_MODEL(history->domain_list),&new_iter,
path);
nsgtk_history_domain_set_visible(
GTK_TREE_MODEL(history->domain_list), NULL,
&new_iter, result);
}
g_free(title);
g_free(address);
g_free(domain);
return result;
}
gboolean nsgtk_history_filter_sites(GtkTreeModel *model, GtkTreeIter *iter,
GString *domain_filter)
{
gchar *domain;
gboolean domain_match;
gtk_tree_model_get(model, iter, SITE_DOMAIN, &domain, -1);
if (domain && domain_filter->str)
domain_match = g_str_equal(domain, domain_filter->str) ||
g_str_equal(domain_filter->str,
domainAll);
else
domain_match = FALSE;
g_free(domain);
return domain_match;
}
void nsgtk_history_domain_sort_changed(GtkComboBox *combo)
{
gint domain_options[] = { DOM_DOMAIN, DOM_LASTVISIT, DOM_TOTALVISITS };
gint site_options[] = { SITE_TITLE, SITE_LASTVISIT, SITE_TOTALVISITS };
gint sort = gtk_combo_box_get_active(combo);
gtk_tree_sortable_set_sort_column_id(
GTK_TREE_SORTABLE(history->domain_sort),
domain_options[sort], GTK_SORT_ASCENDING);
gtk_tree_sortable_set_sort_column_id(
GTK_TREE_SORTABLE(history->site_sort),
site_options[sort], GTK_SORT_ASCENDING);
}
gint nsgtk_history_domain_sort_compare(GtkTreeModel *model, GtkTreeIter *a,
GtkTreeIter *b, gint sort_column)
{
gint comparable_a;
gint comparable_b;
gtk_tree_model_get(model, a, sort_column, &comparable_a, -1);
gtk_tree_model_get(model, b, sort_column, &comparable_b, -1);
/* Make sure "All" stays at the top */
if (comparable_a < 0 || comparable_b < 0)
return comparable_a - comparable_b;
else
return comparable_b - comparable_a;
}
void nsgtk_history_domain_set_visible (GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gboolean has_sites)
{
gchar *string = gtk_tree_model_get_string_from_iter(model, iter);
if (!g_str_equal(string, "0")) /* "All" */
gtk_list_store_set(GTK_LIST_STORE(model), iter,
DOM_HAS_SITES, has_sites, -1);
g_free(string);
}
void nsgtk_history_search()
{
gtk_tree_model_foreach(GTK_TREE_MODEL(history->domain_list),
(GtkTreeModelForeachFunc)
nsgtk_history_domain_set_visible, FALSE);
nsgtk_history_show_all();
gtk_tree_model_filter_refilter(
GTK_TREE_MODEL_FILTER(history->history_filter));
}
void nsgtk_history_search_clear (GtkEntry *entry)
{
gtk_entry_set_text(entry, "");
}
gchar *nsgtk_history_date_parse(time_t visit_time)
{
char *date_string = malloc(30);
char format[30];
time_t current_time = time(NULL);
int current_day = localtime(&current_time)->tm_yday;
struct tm *visit_date = localtime(&visit_time);
if (visit_date->tm_yday == current_day)
snprintf(format, 30, "%s %s %%I:%%M %%p",
dateToday, dateAt);
else if (current_day - visit_date->tm_yday == 1)
snprintf(format, 30, "%s %s %%I:%%M %%p",
dateYesterday, dateAt);
else if (current_day - visit_date->tm_yday < 7)
snprintf(format, 30, "%%A %s %%I:%%M %%p",
dateAt);
else
snprintf(format, 30, "%%B %%d, %%Y");
strftime(date_string, 30, format, visit_date);
return date_string;
}
void nsgtk_history_row_activated(GtkTreeView *tv, GtkTreePath *path,
GtkTreeViewColumn *column)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model(tv);
if (gtk_tree_model_get_iter(model, &iter, path))
while (event->widget != NULL)
{
gchar *address;
gtk_tree_model_get(model, &iter, SITE_ADDRESS, &address, -1);
browser_window_create(address, NULL, NULL, true, false);
GtkWidget *w = glade_xml_get_widget(gladeFile, event->widget);
g_signal_connect(G_OBJECT(w), "activate", event->handler,
global_history_window);
event++;
}
}
void nsgtk_history_update_info(GtkTreeSelection *treesel, gboolean domain)
{
GtkTreeIter iter;
GtkTreeModel *model;
gboolean has_selection;
has_selection = gtk_tree_selection_get_selected(treesel, &model, &iter);
/**
* Destroys the global history window and performs any other necessary cleanup
* actions.
*/
void nsgtk_history_destroy(void)
{
/* TODO: what about gladeFile? */
history_global_cleanup();
nsgtk_treeview_destroy(global_history_window);
}
/* file menu*/
MENUHANDLER(export)
{
GtkWidget *save_dialog;
save_dialog = gtk_file_chooser_dialog_new("Save File",
wndHistory,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
if (has_selection && domain) {
gchar *b;
gint i;
char buf[20];
gboolean all = g_str_equal(gtk_tree_model_get_string_from_iter(
model, &iter), "0");
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
getenv("HOME") ? getenv("HOME") : "/");
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
"history.html");
if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) {
gchar *filename = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(save_dialog));
/* Address */
gtk_tree_model_get(model, &iter, DOM_DOMAIN, &b, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryAddress")),
all ? "-" : b);
g_free(b);
/* Last Visit */
gtk_tree_model_get(model, &iter, DOM_LASTVISIT, &i, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryLastVisit")),
nsgtk_history_date_parse(i));
/* Total Visits */
gtk_tree_model_get(model, &iter, DOM_TOTALVISITS, &i, -1);
snprintf(buf, 20, "%d", i);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryVisits")),
buf);
} else if (has_selection){
GdkPixbuf *thumb;
gchar *b;
gint i;
char buf[20];
/* Address */
gtk_tree_model_get(model, &iter, SITE_ADDRESS, &b, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryAddress")), b);
g_free(b);
/* Last Visit */
gtk_tree_model_get(model, &iter, SITE_LASTVISIT, &i, -1);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryLastVisit")),
nsgtk_history_date_parse(i));
/* Total Visits */
gtk_tree_model_get(model, &iter, SITE_TOTALVISITS, &i, -1);
snprintf(buf, 20, "%d", i);
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeFile,
"labelHistoryVisits")), buf);
gtk_tree_model_get(model, &iter, SITE_THUMBNAIL, &thumb, -1);
gtk_image_set_from_pixbuf(GTK_IMAGE(
glade_xml_get_widget(gladeFile,
"imageThumbnail")), thumb);
g_object_set(G_OBJECT(glade_xml_get_widget(
gladeFile, "imageFrame")),
"visible", (bool)thumb, NULL);
history_global_export(filename);
g_free(filename);
}
}
void nsgtk_history_scroll_top (GtkScrolledWindow *scrolled_window)
{
GtkAdjustment *adjustment =
gtk_scrolled_window_get_vadjustment(scrolled_window);
gtk_adjustment_set_value(adjustment, 0);
gtk_scrolled_window_set_vadjustment(scrolled_window, adjustment);
gtk_widget_destroy(save_dialog);
return TRUE;
}
void global_history_add(const char *url)
/* edit menu */
MENUHANDLER(delete_selected)
{
const struct url_data *data;
data = urldb_get_url_data(url);
if (!data)
return;
nsgtk_history_add_internal(url, data);
history_global_delete_selected();
return TRUE;
}
MENUHANDLER(delete_all)
{
history_global_delete_all();
return TRUE;
}
MENUHANDLER(select_all)
{
history_global_select_all();
return TRUE;
}
MENUHANDLER(clear_selection)
{
history_global_clear_selection();
return TRUE;
}
/* view menu*/
MENUHANDLER(expand_all)
{
history_global_expand_all();
return TRUE;
}
MENUHANDLER(expand_directories)
{
history_global_expand_directories();
return TRUE;
}
MENUHANDLER(expand_addresses)
{
history_global_expand_addresses();
return TRUE;
}
MENUHANDLER(collapse_all)
{
history_global_collapse_all();
return TRUE;
}
MENUHANDLER(collapse_directories)
{
history_global_collapse_directories();
return TRUE;
}
MENUHANDLER(collapse_addresses)
{
history_global_collapse_addresses();
return TRUE;
}
MENUHANDLER(launch)
{
history_global_launch_selected();
return TRUE;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -23,22 +24,7 @@
extern GtkWindow *wndHistory;
struct history_model {
GtkListStore *history_list;
GtkTreeModel *history_filter;
GtkTreeModel *site_filter;
GtkTreeModel *site_sort;
GtkTreeView *site_treeview;
GtkTreeSelection *site_selection;
GtkListStore *domain_list;
GtkTreeModel *domain_filter;
GHashTable *domain_hash;
GtkTreeModel *domain_sort;
GtkTreeView *domain_treeview;
GtkTreeSelection *domain_selection;
};
bool nsgtk_history_init(void);
void nsgtk_history_destroy(void);
#endif /* __NSGTK_HISTORY_H__ */

277
gtk/gtk_hotlist.c Normal file
View File

@ -0,0 +1,277 @@
/*
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/hotlist.h"
#include "desktop/options.h"
#include "desktop/plotters.h"
#include "desktop/tree.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_hotlist.h"
#include "gtk/options.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_scaffolding.h"
#include "gtk/gtk_treeview.h"
#include "utils/log.h"
#define GLADE_NAME "hotlist.glade"
#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
gpointer g)
struct menu_events {
const char *widget;
GCallback handler;
};
static void nsgtk_hotlist_init_menu(void);
/* file menu*/
MENUPROTO(export);
MENUPROTO(new_folder);
MENUPROTO(new_entry);
/* edit menu */
MENUPROTO(edit_selected);
MENUPROTO(delete_selected);
MENUPROTO(select_all);
MENUPROTO(clear_selection);
/* view menu*/
MENUPROTO(expand_all);
MENUPROTO(expand_directories);
MENUPROTO(expand_addresses);
MENUPROTO(collapse_all);
MENUPROTO(collapse_directories);
MENUPROTO(collapse_addresses);
MENUPROTO(launch);
static struct menu_events menu_events[] = {
/* file menu*/
MENUEVENT(export),
MENUEVENT(new_folder),
MENUEVENT(new_entry),
/* edit menu */
MENUEVENT(edit_selected),
MENUEVENT(delete_selected),
MENUEVENT(select_all),
MENUEVENT(clear_selection),
/* view menu*/
MENUEVENT(expand_all),
MENUEVENT(expand_directories),
MENUEVENT(expand_addresses),
MENUEVENT(collapse_all),
MENUEVENT(collapse_directories),
MENUEVENT(collapse_addresses),
MENUEVENT(launch),
{NULL, NULL}
};
static struct nsgtk_treeview *hotlist_window;
static GladeXML *gladeFile;
GtkWindow *wndHotlist;
/**
* Creates the window for the hotlist tree.
*/
void nsgtk_hotlist_init()
{
gchar *glade_location = g_strconcat(res_dir_location, GLADE_NAME, NULL);
gladeFile = glade_xml_new(glade_location, NULL, NULL);
g_free(glade_location);
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
glade_xml_signal_autoconnect(gladeFile);
wndHotlist = GTK_WINDOW(glade_xml_get_widget(gladeFile, "wndHotlist"));
window = wndHotlist;
scrolled = GTK_SCROLLED_WINDOW(glade_xml_get_widget(gladeFile,
"hotlistScrolled"));
drawing_area = GTK_DRAWING_AREA(glade_xml_get_widget(gladeFile,
"hotlistDrawingArea"));
hotlist_window = nsgtk_treeview_create(hotlist_get_tree_flags(), window,
scrolled, drawing_area);
if (hotlist_window == NULL)
return;
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
CONNECT(window, "delete_event", gtk_widget_hide_on_delete, NULL);
CONNECT(window, "hide", nsgtk_tree_window_hide, hotlist_window);
hotlist_initialise(nsgtk_treeview_get_tree(hotlist_window),
option_hotlist_path);
nsgtk_hotlist_init_menu();
}
/**
* Connects menu events in the hotlist window.
*/
void nsgtk_hotlist_init_menu(void)
{
struct menu_events *event = menu_events;
while (event->widget != NULL)
{
GtkWidget *w = glade_xml_get_widget(gladeFile, event->widget);
g_signal_connect(G_OBJECT(w), "activate", event->handler,
hotlist_window);
event++;
}
}
/**
* Destroys the hotlist window and performs any other necessary cleanup actions.
*/
void nsgtk_hotlist_destroy(void)
{
/* TODO: what about gladeFile? */
hotlist_cleanup(option_hotlist_path);
nsgtk_treeview_destroy(hotlist_window);
}
/* file menu*/
MENUHANDLER(export)
{
GtkWidget *save_dialog;
save_dialog = gtk_file_chooser_dialog_new("Save File",
wndHotlist,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
getenv("HOME") ? getenv("HOME") : "/");
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
"hotlist.html");
if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) {
gchar *filename = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(save_dialog));
hotlist_export(filename);
g_free(filename);
}
gtk_widget_destroy(save_dialog);
return TRUE;
}
MENUHANDLER(new_folder)
{
hotlist_add_folder();
return TRUE;
}
MENUHANDLER(new_entry)
{
hotlist_add_entry();
return TRUE;
}
/* edit menu */
MENUHANDLER(edit_selected)
{
hotlist_edit_selected();
return TRUE;
}
MENUHANDLER(delete_selected)
{
hotlist_delete_selected();
return TRUE;
}
MENUHANDLER(select_all)
{
hotlist_select_all();
return TRUE;
}
MENUHANDLER(clear_selection)
{
hotlist_clear_selection();
return TRUE;
}
/* view menu*/
MENUHANDLER(expand_all)
{
hotlist_expand_all();
return TRUE;
}
MENUHANDLER(expand_directories)
{
hotlist_expand_directories();
return TRUE;
}
MENUHANDLER(expand_addresses)
{
hotlist_expand_addresses();
return TRUE;
}
MENUHANDLER(collapse_all)
{
hotlist_collapse_all();
return TRUE;
}
MENUHANDLER(collapse_directories)
{
hotlist_collapse_directories();
return TRUE;
}
MENUHANDLER(collapse_addresses)
{
hotlist_collapse_addresses();
return TRUE;
}
MENUHANDLER(launch)
{
hotlist_launch_selected();
return TRUE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -16,26 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "content/urldb.h"
#include "desktop/browser.h"
/** \file
* GTK hotlist (interface).
*/
void global_history_add(const char *url)
{
const struct url_data *data;
#ifndef __NSGTK_HOTLIST_H__
#define __NSGTK_HOTLIST_H__
data = urldb_get_url_data(url);
if (!data)
return;
#include <gtk/gtk.h>
extern GtkWindow *wndHotlist;
}
void global_history_add_recent(const char *url)
{
}
char **global_history_get_recent(int *count)
{
return NULL;
}
void nsgtk_hotlist_init(void);
void nsgtk_hotlist_destroy(void);
#endif /* __NSGTK_HOTLIST_H__ */

View File

@ -397,6 +397,7 @@ static struct nsgtk_nav_menu *nsgtk_menu_nav_menu(GtkAccelGroup *group,
free(ret);
return NULL;
}
IMAGE_ITEM(nav, back, gtkBack, ret, group);
IMAGE_ITEM(nav, forward, gtkForward, ret, group);
IMAGE_ITEM(nav, home, gtkHome, ret, group);
@ -407,6 +408,8 @@ static struct nsgtk_nav_menu *nsgtk_menu_nav_menu(GtkAccelGroup *group,
IMAGE_ITEM(nav, addbookmarks, gtkAddBookMarks, ret, group);
IMAGE_ITEM(nav, showbookmarks, gtkShowBookMarks, ret, group);
ADD_SEP(nav, ret);
IMAGE_ITEM(nav, showcookies, gtkShowCookies, ret, group);
ADD_SEP(nav, ret);
IMAGE_ITEM(nav, openlocation, gtkOpenLocation, ret, group);
ATTACH_PARENT(parent, gtkNavigate, ret->nav, group);

View File

@ -78,6 +78,7 @@ struct nsgtk_nav_menu {
GtkImageMenuItem *globalhistory_menuitem;
GtkImageMenuItem *addbookmarks_menuitem;
GtkImageMenuItem *showbookmarks_menuitem;
GtkImageMenuItem *showcookies_menuitem;
GtkImageMenuItem *openlocation_menuitem;
};

View File

@ -89,9 +89,9 @@ void nsgtk_set_colour(colour c)
g / 255.0, b / 255.0, 1.0);
}
/** Plot a caret.
/** Plot a caret.
*
* @note It is assumed that the plotters have been set up.
* @note It is assumed that the plotters have been set up.
*/
void nsgtk_plot_caret(int x, int y, int h)
{
@ -234,8 +234,12 @@ static bool nsgtk_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *
else
cairo_set_line_width(current_cr, style->stroke_width);
cairo_move_to(current_cr, x0 + 0.5, y0 + 0.5);
cairo_line_to(current_cr, x1 + 0.5, y1 + 0.5);
/* core expects horizontal and vertical lines to be on pixels, not
* between pixels */
cairo_move_to(current_cr, (x0 == x1) ? x0 + 0.5 : x0,
(y0 == y1) ? y0 + 0.5 : y0);
cairo_line_to(current_cr, (x0 == x1) ? x1 + 0.5 : x1,
(y0 == y1) ? y1 + 0.5 : y1);
cairo_stroke(current_cr);
return true;
@ -304,7 +308,7 @@ static bool nsgtk_plot_polygon(const int *p, unsigned int n, const plot_style_t
static bool nsgtk_plot_text(int x, int y, const char *text, size_t length,
static bool nsgtk_plot_text(int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle)
{
return nsfont_paint(x, y, text, length, fstyle);

View File

@ -34,6 +34,7 @@
#include "css/utils.h"
#include "desktop/browser.h"
#include "desktop/history_core.h"
#include "desktop/hotlist.h"
#include "desktop/gui.h"
#include "desktop/netsurf.h"
#include "desktop/options.h"
@ -49,6 +50,8 @@
#include "desktop/searchweb.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "desktop/tree.h"
#include "gtk/gtk_cookies.h"
#include "gtk/gtk_completion.h"
#include "gtk/dialogs/gtk_options.h"
#include "gtk/dialogs/gtk_about.h"
@ -57,6 +60,7 @@
#include "gtk/gtk_download.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_history.h"
#include "gtk/gtk_hotlist.h"
#include "gtk/gtk_menu.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_print.h"
@ -66,6 +70,7 @@
#include "gtk/gtk_theme.h"
#include "gtk/gtk_throbber.h"
#include "gtk/gtk_toolbar.h"
#include "gtk/gtk_treeview.h"
#include "gtk/gtk_window.h"
#include "gtk/options.h"
#include "gtk/sexy_icon_entry.h"
@ -217,7 +222,7 @@ void nsgtk_window_close(struct gtk_scaffolding *g)
if ((g->history_window) && (g->history_window->window)) {
gtk_widget_destroy(GTK_WIDGET(g->history_window->window));
}
if (--open_windows == 0)
netsurf_quit = true;
@ -1263,17 +1268,34 @@ MULTIHANDLER(globalhistory)
{
gtk_widget_show(GTK_WIDGET(wndHistory));
gdk_window_raise(GTK_WIDGET(wndHistory)->window);
return TRUE;
}
MULTIHANDLER(addbookmarks)
{
struct browser_window *bw = gui_window_get_browser_window(g->top_level);
if (bw == NULL || bw->current_content == NULL ||
content_get_url(bw->current_content) == NULL)
return TRUE;
hotlist_add_page(content_get_url(bw->current_content));
return TRUE;
}
MULTIHANDLER(showbookmarks)
{
gtk_widget_show(GTK_WIDGET(wndHotlist));
gdk_window_raise(GTK_WIDGET(wndHotlist)->window);
return TRUE;
}
MULTIHANDLER(showcookies)
{
gtk_widget_show(GTK_WIDGET(wndCookies));
gdk_window_raise(GTK_WIDGET(wndCookies)->window);
return TRUE;
}
@ -1394,6 +1416,7 @@ gboolean nsgtk_history_button_press_event(GtkWidget *widget,
return TRUE;
}
#define GET_WIDGET(x) glade_xml_get_widget(g->xml, (x))
nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
@ -1582,6 +1605,7 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
gtk_scrolled_window_add_with_viewport(g->history_window->scrolled,
GTK_WIDGET(g->history_window->drawing_area));
gtk_widget_show(GTK_WIDGET(g->history_window->drawing_area));
/* set up URL bar completion */
g->url_bar_completion = gtk_entry_completion_new();
@ -1613,7 +1637,7 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
nsgtk_history_button_press_event, g->history_window);
CONNECT(g->history_window->window, "delete_event",
gtk_widget_hide_on_delete, NULL);
g_signal_connect_after(g->notebook, "page-added",
G_CALLBACK(nsgtk_window_tabs_num_changed), g);
g_signal_connect_after(g->notebook, "page-removed",
@ -2408,6 +2432,7 @@ void nsgtk_scaffolding_toolbar_init(struct gtk_scaffolding *g)
ITEM_MAIN(GLOBALHISTORY, nav, globalhistory);
ITEM_MAIN(ADDBOOKMARKS, nav, addbookmarks);
ITEM_MAIN(SHOWBOOKMARKS, nav, showbookmarks);
ITEM_MAIN(SHOWCOOKIES, nav, showcookies);
ITEM_MAIN(OPENLOCATION, nav, openlocation);
ITEM_MAIN(CONTENTS, help, contents);
ITEM_MAIN(INFO, help, info);
@ -2437,8 +2462,6 @@ void nsgtk_scaffolding_toolbar_init(struct gtk_scaffolding *g)
SENSITIVITY(CONTENTS);
SENSITIVITY(DRAWFILE);
SENSITIVITY(POSTSCRIPT);
SENSITIVITY(ADDBOOKMARKS);
SENSITIVITY(SHOWBOOKMARKS);
SENSITIVITY(NEXTTAB);
SENSITIVITY(PREVTAB);
SENSITIVITY(CLOSETAB);

View File

@ -73,6 +73,7 @@ typedef enum {
GLOBALHISTORY_BUTTON,
ADDBOOKMARKS_BUTTON,
SHOWBOOKMARKS_BUTTON,
SHOWCOOKIES_BUTTON,
OPENLOCATION_BUTTON,
NEXTTAB_BUTTON,
PREVTAB_BUTTON,
@ -209,6 +210,7 @@ MULTIPROTO(localhistory);
MULTIPROTO(globalhistory);
MULTIPROTO(addbookmarks);
MULTIPROTO(showbookmarks);
MULTIPROTO(showcookies);
MULTIPROTO(openlocation);
/* tabs menu */

View File

@ -447,6 +447,7 @@ struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s)
SET_BUTTON_IMAGE(cachetheme, GLOBALHISTORY, theme)
SET_BUTTON_IMAGE(cachetheme, ADDBOOKMARKS, theme)
SET_BUTTON_IMAGE(cachetheme, SHOWBOOKMARKS, theme)
SET_BUTTON_IMAGE(cachetheme, SHOWCOOKIES, theme)
SET_BUTTON_IMAGE(cachetheme, OPENLOCATION, theme)
SET_BUTTON_IMAGE(cachetheme, NEXTTAB, theme)
SET_BUTTON_IMAGE(cachetheme, PREVTAB, theme)
@ -571,6 +572,7 @@ void nsgtk_theme_prepare(void)
CACHE_IMAGE(GLOBALHISTORY, globalhistory, path);
CACHE_IMAGE(ADDBOOKMARKS, addbookmarks, path);
CACHE_IMAGE(SHOWBOOKMARKS, showbookmarks, path);
CACHE_IMAGE(SHOWCOOKIES, showcookies, path);
CACHE_IMAGE(OPENLOCATION, openlocation, path);
CACHE_IMAGE(NEXTTAB, nexttab, path);
CACHE_IMAGE(PREVTAB, prevtab, path);

View File

@ -822,6 +822,7 @@ GtkWidget *nsgtk_toolbar_make_widget(nsgtk_scaffolding *g,
MAKE_MENUBUTTON(GLOBALHISTORY, gtkGlobalHistory)
MAKE_MENUBUTTON(ADDBOOKMARKS, gtkAddBookMarks)
MAKE_MENUBUTTON(SHOWBOOKMARKS, gtkShowBookMarks)
MAKE_MENUBUTTON(SHOWCOOKIES, gtkShowCookies)
MAKE_MENUBUTTON(OPENLOCATION, gtkOpenLocation)
MAKE_MENUBUTTON(NEXTTAB, gtkNextTab)
MAKE_MENUBUTTON(PREVTAB, gtkPrevTab)
@ -986,6 +987,7 @@ DATAHANDLER(localhistory, LOCALHISTORY, window)
DATAHANDLER(globalhistory, GLOBALHISTORY, window)
DATAHANDLER(addbookmarks, ADDBOOKMARKS, window)
DATAHANDLER(showbookmarks, SHOWBOOKMARKS, window)
DATAHANDLER(showcookies, SHOWCOOKIES, window)
DATAHANDLER(openlocation, OPENLOCATION, window)
DATAHANDLER(nexttab, NEXTTAB, window)
DATAHANDLER(prevtab, PREVTAB, window)

View File

@ -74,6 +74,7 @@ TOOLPROTO(localhistory);
TOOLPROTO(globalhistory);
TOOLPROTO(addbookmarks);
TOOLPROTO(showbookmarks);
TOOLPROTO(showcookies);
TOOLPROTO(openlocation);
TOOLPROTO(nexttab);
TOOLPROTO(prevtab);

View File

@ -1,5 +1,6 @@
/*
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -20,101 +21,107 @@
* Generic tree handling (implementation).
*/
#include <assert.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
#include "desktop/plotters.h"
#include "gtk/gtk_gui.h"
#include "gtk/gtk_plotters.h"
#include "gtk/gtk_treeview.h"
#include "utils/log.h"
#include "utils/utils.h"
struct nsgtk_treeview {
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
int mouse_pressed_x;
int mouse_pressed_y;
browser_mouse_state mouse_state;
struct tree *tree;
};
/**
* Sets the origin variables to the correct values for a specified tree
*
* \param tree the tree to set the origin for
*/
void tree_initialise_redraw(struct tree *tree) {
const char tree_directory_icon_name[] = "directory.png";
const char tree_content_icon_name[] = "content.png";
static void nsgtk_tree_redraw_request(int x, int y, int width, int height,
void *data);
static void nsgtk_tree_resized(struct tree *tree, int width, int height, void *data);
static void nsgtk_tree_scroll_visible(int y, int height, void *data);
static void nsgtk_tree_get_window_dimensions(int *width, int *height, void *data);
static const struct treeview_table nsgtk_tree_callbacks = {
.redraw_request = nsgtk_tree_redraw_request,
.resized = nsgtk_tree_resized,
.scroll_visible = nsgtk_tree_scroll_visible,
.get_window_dimensions = nsgtk_tree_get_window_dimensions
};
struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
GtkWindow *window, GtkScrolledWindow *scrolled,
GtkDrawingArea *drawing_area)
{
struct nsgtk_treeview *tv;
tv = malloc(sizeof(struct nsgtk_treeview));
if (tv == NULL) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
return NULL;
}
tv->window = window;
tv->scrolled = scrolled;
tv->drawing_area = drawing_area;
tv->tree = tree_create(flags, &nsgtk_tree_callbacks, tv);
tv->mouse_state = 0;
gtk_widget_modify_bg(GTK_WIDGET(drawing_area), GTK_STATE_NORMAL,
&((GdkColor) { 0, 0xffff, 0xffff, 0xffff } ));
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
CONNECT(drawing_area, "expose_event",
nsgtk_tree_window_expose_event,
tv->tree);
CONNECT(drawing_area, "button_press_event",
nsgtk_tree_window_button_press_event,
tv);
CONNECT(drawing_area, "button_release_event",
nsgtk_tree_window_button_release_event,
tv);
CONNECT(drawing_area, "motion_notify_event",
nsgtk_tree_window_motion_notify_event,
tv);
CONNECT(drawing_area, "key_press_event",
nsgtk_tree_window_keypress_event,
tv);
return tv;
}
/**
* Informs the current window manager that an area requires updating.
*
* \param tree the tree that is requesting a redraw
* \param x the x co-ordinate of the redraw area
* \param y the y co-ordinate of the redraw area
* \param width the width of the redraw area
* \param height the height of the redraw area
*/
void tree_redraw_area(struct tree *tree, int x, int y, int width, int height) {
void nsgtk_treeview_destroy(struct nsgtk_treeview *tv)
{
tree_delete(tv->tree);
gtk_widget_destroy(GTK_WIDGET(tv->window));
free(tv);
}
/**
* Draws a line.
*
* \param x the x co-ordinate
* \param x the y co-ordinate
* \param x the width of the line
* \param x the height of the line
*/
void tree_draw_line(int x, int y, int width, int height) {
struct tree *nsgtk_treeview_get_tree(struct nsgtk_treeview *tv)
{
return tv->tree;
}
/**
* Draws an element, including any expansion icons
*
* \param tree the tree to draw an element for
* \param element the element to draw
*/
void tree_draw_node_element(struct tree *tree, struct node_element *element) {
}
/**
* Draws an elements expansion icon
*
* \param tree the tree to draw the expansion for
* \param element the element to draw the expansion for
*/
void tree_draw_node_expansion(struct tree *tree, struct node *node) {
}
/**
* Recalculates the dimensions of a node element.
*
* \param element the element to recalculate
*/
void tree_recalculate_node_element(struct node_element *element) {
}
/**
* Sets a node element as having a specific sprite.
*
* \param node the node to update
* \param sprite the sprite to use
* \param selected the expanded sprite name to use
*/
void tree_set_node_sprite(struct node *node, const char *sprite,
const char *expanded) {
}
/**
* Sets a node element as having a folder sprite
*
* \param node the node to update
*/
void tree_set_node_sprite_folder(struct node *node) {
}
/**
* Updates the node details for a URL node.
* The internal node dimensions are not updated.
*
* \param node the node to update
*/
void tree_update_URL_node(struct node *node, const char *url,
const struct url_data *data) {
void nsgtk_tree_redraw_request(int x, int y, int width, int height, void *data)
{
struct nsgtk_treeview *tw = data;
gtk_widget_queue_draw_area(GTK_WIDGET(tw->drawing_area),
x, y, width, height);
}
@ -123,5 +130,413 @@ void tree_update_URL_node(struct node *node, const char *url,
*
* \param tree the tree to update the owner of
*/
void tree_resized(struct tree *tree) {
void nsgtk_tree_resized(struct tree *tree, int width, int height, void *data)
{
struct nsgtk_treeview *tw = data;
gtk_widget_set_size_request(GTK_WIDGET(tw->drawing_area),
width, height);
return;
}
/**
* Translates a content_type to the name of a respective icon
*
* \param content_type content type
* \param buffer buffer for the icon name
*/
void tree_icon_name_from_content_type(char *buffer, content_type type)
{
// TODO: design/acquire icons
switch (type) {
case CONTENT_HTML:
case CONTENT_TEXTPLAIN:
case CONTENT_CSS:
#if defined(WITH_MNG) || defined(WITH_PNG)
case CONTENT_PNG:
#endif
#ifdef WITH_MNG
case CONTENT_JNG:
case CONTENT_MNG:
#endif
#ifdef WITH_JPEG
case CONTENT_JPEG:
#endif
#ifdef WITH_GIF
case CONTENT_GIF:
#endif
#ifdef WITH_BMP
case CONTENT_BMP:
case CONTENT_ICO:
#endif
#ifdef WITH_SPRITE
case CONTENT_SPRITE:
#endif
#ifdef WITH_DRAW
case CONTENT_DRAW:
#endif
#ifdef WITH_ARTWORKS
case CONTENT_ARTWORKS:
#endif
#ifdef WITH_NS_SVG
case CONTENT_SVG:
#endif
default:
sprintf(buffer, tree_content_icon_name);
break;
}
}
/**
* Scrolls the tree to make an element visible
*
* \param y Y coordinate of the element
* \param height height of the element
* \param data user data assigned to the tree on tree creation
*/
void nsgtk_tree_scroll_visible(int y, int height, void *data)
{
int y0, y1;
gdouble page;
struct nsgtk_treeview *tw = data;
GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(tw->scrolled);
assert(vadj);
g_object_get(vadj, "page-size", &page, NULL);
y0 = (int)(gtk_adjustment_get_value(vadj));
y1 = y0 + page;
if ((y >= y0) && (y + height <= y1))
return;
if (y + height > y1)
y0 = y0 + (y + height - y1);
if (y < y0)
y0 = y;
gtk_adjustment_set_value(vadj, y0);
}
/**
* Retrieves the dimensions of the window with the tree
*
* \param data user data assigned to the tree on tree creation
* \param width will be updated to window width if not NULL
* \param height will be updated to window height if not NULL
*/
void nsgtk_tree_get_window_dimensions(int *width, int *height, void *data)
{
struct nsgtk_treeview *tw = data;
GtkAdjustment *vadj;
GtkAdjustment *hadj;
gdouble page;
if (width != NULL) {
hadj = gtk_scrolled_window_get_hadjustment(tw->scrolled);
g_object_get(hadj, "page-size", &page, NULL);
*width = page;
}
if (height != NULL) {
vadj = gtk_scrolled_window_get_vadjustment(tw->scrolled);
g_object_get(vadj, "page-size", &page, NULL);
*height = page;
}
}
/* signal handler functions for a tree window */
gboolean nsgtk_tree_window_expose_event(GtkWidget *widget,
GdkEventExpose *event, gpointer g)
{
struct tree *tree = (struct tree *) g;
int x, y, width, height;
x = event->area.x;
y = event->area.y;
width = event->area.width;
height = event->area.height;
current_widget = widget;
current_drawable = widget->window;
current_gc = gdk_gc_new(current_drawable);
#ifdef CAIRO_VERSION
current_cr = gdk_cairo_create(current_drawable);
#endif
plot = nsgtk_plotters;
nsgtk_plot_set_scale(1.0);current_widget = widget;
current_drawable = widget->window;
current_gc = gdk_gc_new(current_drawable);
#ifdef CAIRO_VERSION
current_cr = gdk_cairo_create(current_drawable);
#endif
plot = nsgtk_plotters;
nsgtk_plot_set_scale(1.0);
tree_set_redraw(tree, true);
tree_draw(tree, 0, 0, x, y, width, height);
current_widget = NULL;
g_object_unref(current_gc);
#ifdef CAIRO_VERSION
cairo_destroy(current_cr);
#endif
return FALSE;
}
void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g)
{
struct nsgtk_treeview *tw = g;
struct tree *tree = tw->tree;
if (tree != NULL)
tree_set_redraw(tree, false);
}
gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
struct nsgtk_treeview *tw = g;
struct tree *tree = tw->tree;
gtk_widget_grab_focus(GTK_WIDGET(tw->drawing_area));
tw->mouse_pressed_x = event->x;
tw->mouse_pressed_y = event->y;
if (event->type == GDK_2BUTTON_PRESS)
tw->mouse_state = BROWSER_MOUSE_DOUBLE_CLICK;
switch (event->button) {
case 1: tw->mouse_state |= BROWSER_MOUSE_PRESS_1; break;
case 3: tw->mouse_state |= BROWSER_MOUSE_PRESS_2; break;
}
/* Handle the modifiers too */
if (event->state & GDK_SHIFT_MASK)
tw->mouse_state |= BROWSER_MOUSE_MOD_1;
if (event->state & GDK_CONTROL_MASK)
tw->mouse_state |= BROWSER_MOUSE_MOD_2;
if (event->state & GDK_MOD1_MASK)
tw->mouse_state |= BROWSER_MOUSE_MOD_3;
tree_mouse_action(tree, tw->mouse_state, event->x, event->y);
return TRUE;
}
gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
bool ctrl = event->state & GDK_CONTROL_MASK;
bool alt = event->state & GDK_MOD1_MASK;
struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
struct tree *tree = tw->tree;
/* We consider only button 1 clicks as double clicks.
* If the mouse state is PRESS then we are waiting for a release to emit
* a click event, otherwise just reset the state to nothing*/
if (tw->mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
if (tw->mouse_state & BROWSER_MOUSE_PRESS_1)
tw->mouse_state ^= BROWSER_MOUSE_PRESS_1;
else if (tw->mouse_state & BROWSER_MOUSE_PRESS_2)
tw->mouse_state ^= (BROWSER_MOUSE_PRESS_2 |
BROWSER_MOUSE_DOUBLE_CLICK);
} else if (tw->mouse_state & BROWSER_MOUSE_PRESS_1)
tw->mouse_state ^=
(BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1);
else if (tw->mouse_state & BROWSER_MOUSE_PRESS_2)
tw->mouse_state ^= (BROWSER_MOUSE_PRESS_2 |
BROWSER_MOUSE_CLICK_2);
/* Handle modifiers being removed */
if (tw->mouse_state & BROWSER_MOUSE_MOD_1 && !shift)
tw->mouse_state ^= BROWSER_MOUSE_MOD_1;
if (tw->mouse_state & BROWSER_MOUSE_MOD_2 && !ctrl)
tw->mouse_state ^= BROWSER_MOUSE_MOD_2;
if (tw->mouse_state & BROWSER_MOUSE_MOD_3 && !alt)
tw->mouse_state ^= BROWSER_MOUSE_MOD_3;
if (tw->mouse_state &
(BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2
| BROWSER_MOUSE_DOUBLE_CLICK))
tree_mouse_action(tree, tw->mouse_state,
event->x, event->y);
else
tree_drag_end(tree, tw->mouse_state,
tw->mouse_pressed_x,
tw->mouse_pressed_y,
event->x, event->y);
tw->mouse_state = 0;
return TRUE;
}
gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
bool ctrl = event->state & GDK_CONTROL_MASK;
bool alt = event->state & GDK_MOD1_MASK;
struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
struct tree *tree = tw->tree;
/* Handle modifiers being removed */
if (tw->mouse_state & BROWSER_MOUSE_MOD_1 && !shift)
tw->mouse_state ^= BROWSER_MOUSE_MOD_1;
if (tw->mouse_state & BROWSER_MOUSE_MOD_2 && !ctrl)
tw->mouse_state ^= BROWSER_MOUSE_MOD_2;
if (tw->mouse_state & BROWSER_MOUSE_MOD_3 && !alt)
tw->mouse_state ^= BROWSER_MOUSE_MOD_3;
if (tw->mouse_state & BROWSER_MOUSE_PRESS_1) {
/* Start button 1 drag */
tree_mouse_action(tree, BROWSER_MOUSE_DRAG_1,
tw->mouse_pressed_x, tw->mouse_pressed_y);
/* Replace PRESS with HOLDING and declare drag in progress */
tw->mouse_state ^= (BROWSER_MOUSE_PRESS_1 |
BROWSER_MOUSE_HOLDING_1);
tw->mouse_state |= BROWSER_MOUSE_DRAG_ON;
return TRUE;
}
else if (tw->mouse_state & BROWSER_MOUSE_PRESS_2){
/* Start button 2s drag */
tree_mouse_action(tree, BROWSER_MOUSE_DRAG_2,
tw->mouse_pressed_x, tw->mouse_pressed_y);
/* Replace PRESS with HOLDING and declare drag in progress */
tw->mouse_state ^= (BROWSER_MOUSE_PRESS_2 |
BROWSER_MOUSE_HOLDING_2);
tw->mouse_state |= BROWSER_MOUSE_DRAG_ON;
return TRUE;
}
if (tw->mouse_state & (BROWSER_MOUSE_HOLDING_1 |
BROWSER_MOUSE_HOLDING_2))
tree_mouse_action(tree, tw->mouse_state, event->x,
event->y);
return TRUE;
}
gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
gpointer g)
{
struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
struct tree *tree = tw->tree;
uint32_t nskey;
double value;
GtkAdjustment *vscroll;
GtkAdjustment *hscroll;
GtkAdjustment *scroll = NULL;
gdouble hpage, vpage;
bool edited;
nskey = gtk_gui_gdkkey_to_nskey(event);
vscroll = gtk_scrolled_window_get_vadjustment(tw->scrolled);
hscroll = gtk_scrolled_window_get_hadjustment(tw->scrolled);
g_object_get(vscroll, "page-size", &vpage, NULL);
g_object_get(hscroll, "page-size", &hpage, NULL);
edited = tree_is_edited(tree);
switch (event->keyval) {
case GDK_Home:
case GDK_KP_Home:
if (edited)
break;
scroll = vscroll;
value = scroll->lower;
break;
case GDK_End:
case GDK_KP_End:
if (edited)
break;
scroll = vscroll;
value = scroll->upper - vpage;
if (value < scroll->lower)
value = scroll->lower;
break;
case GDK_Left:
case GDK_KP_Left:
if (edited)
break;
scroll = hscroll;
value = gtk_adjustment_get_value(scroll) -
scroll->step_increment;
if (value < scroll->lower)
value = scroll->lower;
break;
case GDK_Up:
case GDK_KP_Up:
scroll = vscroll;
value = gtk_adjustment_get_value(scroll) -
scroll->step_increment;
if (value < scroll->lower)
value = scroll->lower;
break;
case GDK_Right:
case GDK_KP_Right:
if (edited)
break;
scroll = hscroll;
value = gtk_adjustment_get_value(scroll) +
scroll->step_increment;
if (value > scroll->upper - hpage)
value = scroll->upper - hpage;
break;
case GDK_Down:
case GDK_KP_Down:
scroll = vscroll;
value = gtk_adjustment_get_value(scroll) +
scroll->step_increment;
if (value > scroll->upper - vpage)
value = scroll->upper - vpage;
break;
case GDK_Page_Up:
case GDK_KP_Page_Up:
scroll = vscroll;
value = gtk_adjustment_get_value(scroll) -
scroll->page_increment;
if (value < scroll->lower)
value = scroll->lower;
break;
case GDK_Page_Down:
case GDK_KP_Page_Down:
scroll = vscroll;
value = gtk_adjustment_get_value(scroll) +
scroll->page_increment;
if (value > scroll->upper - vpage)
value = scroll->upper - vpage;
break;
default:
tree_keypress(tree, nskey);
return TRUE;
}
if (scroll != NULL)
gtk_adjustment_set_value(scroll, value);
tree_keypress(tree, nskey);
return TRUE;
}

50
gtk/gtk_treeview.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Generic tree handling.
*/
#ifndef __NSGTK_TREEVIEW_H__
#define __NSGTK_TREEVIEW_H__
#include "desktop/browser.h"
struct nsgtk_treeview;
struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
GtkWindow *window, GtkScrolledWindow *scrolled,
GtkDrawingArea *drawing_area);
void nsgtk_treeview_destroy(struct nsgtk_treeview *tv);
struct tree *nsgtk_treeview_get_tree(struct nsgtk_treeview *tv);
gboolean nsgtk_tree_window_expose_event(GtkWidget *, GdkEventExpose *,
gpointer g);
void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g);
gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer g);
gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
GdkEventButton *event, gpointer g);
gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
GdkEventButton *event, gpointer g);
gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
gpointer g);
#endif /*__NSGTK_TREEVIEW_H__*/

View File

@ -606,7 +606,7 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget,
}
gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
gpointer data)
gpointer data)
{
struct gui_window *g = data;
uint32_t nskey = gtk_gui_gdkkey_to_nskey(event);

View File

@ -34,6 +34,7 @@ extern int option_history_age;
extern bool option_hover_urls;
extern bool option_focus_new;
extern bool option_new_blank;
extern char *option_hotlist_path;
extern bool option_source_tab;
extern int option_current_theme;
@ -51,6 +52,7 @@ int option_history_age = 0; \
bool option_hover_urls = false; \
bool option_focus_new = false; \
bool option_new_blank = false; \
char *option_hotlist_path = NULL; \
bool option_source_tab = false;\
int option_current_theme = 0;
@ -68,6 +70,7 @@ int option_current_theme = 0;
{ "hover_urls", OPTION_BOOL, &option_hover_urls}, \
{ "focus_new", OPTION_BOOL, &option_focus_new}, \
{ "new_blank", OPTION_BOOL, &option_new_blank}, \
{ "hotlist_path", OPTION_STRING, &option_hotlist_path}, \
{ "source_tab", OPTION_BOOL, &option_source_tab},\
{ "current_theme", OPTION_INTEGER, &option_current_theme}

174
gtk/res/cookies.glade Normal file
View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Tue Jul 28 17:12:17 2009 -->
<glade-interface>
<widget class="GtkWindow" id="wndCookies">
<property name="title" translatable="yes">NetSurf Cookies</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="default_width">600</property>
<property name="default_height">500</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_UTILITY</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">2</property>
<property name="spacing">2</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu2">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="delete_selected">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Deletes selected nodes</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use_underline">True</property>
<accelerator key="Delete" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="delete_all">
<property name="visible">True</property>
<property name="label" translatable="yes">D_elete all</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="select_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_Select all</property>
<property name="use_underline">True</property>
<accelerator key="A" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="clear_selection">
<property name="visible">True</property>
<property name="label" translatable="yes">_Clear selection</property>
<property name="use_underline">True</property>
<accelerator key="U" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu4">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="expand">
<property name="visible">True</property>
<property name="label" translatable="yes">_Expand</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu5">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="expand_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_domains">
<property name="visible">True</property>
<property name="label" translatable="yes">_Domains</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_cookies">
<property name="visible">True</property>
<property name="label" translatable="yes">_Cookies</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse">
<property name="visible">True</property>
<property name="label" translatable="yes">Collapse</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu6">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="collapse_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_domains">
<property name="visible">True</property>
<property name="label" translatable="yes">_Domains</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_cookies">
<property name="visible">True</property>
<property name="label" translatable="yes">_Cookies</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="cookiesScrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="cookiesViewport">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<child>
<widget class="GtkDrawingArea" id="cookiesDrawingArea">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -8,307 +8,191 @@
<property name="default_width">600</property>
<property name="default_height">500</property>
<property name="type_hint">utility</property>
<signal name="delete_event" handler="gtk_widget_hide"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">2</property>
<property name="spacing">2</property>
<child>
<widget class="GtkHPaned" id="hpaned2">
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">234</property>
<child>
<widget class="GtkVBox" id="vbox28">
<widget class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="spacing">2</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkHBox" id="hbox2">
<widget class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkLabel" id="label1">
<widget class="GtkMenuItem" id="export">
<property name="visible">True</property>
<property name="label" translatable="yes">Sort by</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">1</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="comboSort">
<property name="visible">True</property>
<property name="items" translatable="yes">Name
Last Visited
Number of Visits</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="windowDomain">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">1</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<widget class="GtkTreeView" id="treeDomain">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="rules_hint">True</property>
<property name="label" translatable="yes">_Export</property>
<property name="use_underline">True</property>
<accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox2">
<widget class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="spacing">2</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkHBox" id="hbox1">
<widget class="GtkMenu" id="menu2">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label2">
<widget class="GtkMenuItem" id="delete_selected">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;_Search for&lt;/b&gt;</property>
<property name="use_markup">True</property>
<property name="tooltip" translatable="yes">Deletes selected nodes</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use_underline">True</property>
<accelerator key="Delete" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="delete_all">
<property name="visible">True</property>
<property name="label" translatable="yes">D_elete all</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">1</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entrySearch">
<widget class="GtkMenuItem" id="select_all">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">out</property>
<property name="label" translatable="yes">_Select all</property>
<property name="use_underline">True</property>
<accelerator key="A" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="buttonClearSearch">
<widget class="GtkMenuItem" id="clear_selection">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="focus_on_click">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">_Clear selection</property>
<property name="use_underline">True</property>
<accelerator key="U" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu4">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="expand">
<property name="visible">True</property>
<property name="label" translatable="yes">_Expand</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkImage" id="image1">
<widget class="GtkMenu" id="menu5">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Clear the search entry</property>
<property name="stock">gtk-clear</property>
<property name="icon-size">1</property>
<child>
<widget class="GtkMenuItem" id="expand_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_directories">
<property name="visible">True</property>
<property name="label" translatable="yes">_Directories</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_addresses">
<property name="visible">True</property>
<property name="label" translatable="yes">Add_resses</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="windowSites">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">1</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<widget class="GtkTreeView" id="treeHistory">
<widget class="GtkMenuItem" id="collapse">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="rules_hint">True</property>
<property name="show_expanders">False</property>
<property name="label" translatable="yes">_Collapse</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu6">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="collapse_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_directories">
<property name="visible">True</property>
<property name="label" translatable="yes">_Directories</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_addresses">
<property name="visible">True</property>
<property name="label" translatable="yes">Add_resses</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="spacing">5</property>
<child>
<widget class="GtkTable" id="table1">
<widget class="GtkMenuItem" id="launch">
<property name="visible">True</property>
<property name="border_width">1</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">5</property>
<property name="row_spacing">5</property>
<child>
<widget class="GtkLabel" id="labelHistoryAddress">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">http://netsurf.sf.net/</property>
<property name="ellipsize">middle</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="labelHistoryLastVisit">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Fri Aug 09, 2006</property>
<property name="ellipsize">end</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="labelHistoryVisits">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">2</property>
<property name="ellipsize">end</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label119">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Number of visits</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label118">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Last visited</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label117">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Address</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<property name="tooltip" translatable="yes">Launches the selected addresses</property>
<property name="label" translatable="yes">_Launch</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="imageFrame">
<property name="label_xalign">1</property>
<property name="label_yalign">1</property>
<property name="shadow_type">in</property>
<child>
<widget class="GtkImage" id="imageThumbnail">
<property name="width_request">100</property>
<property name="height_request">86</property>
<property name="visible">True</property>
<property name="stock">gtk-file</property>
<property name="icon-size">6</property>
</widget>
</child>
<child>
<placeholder/>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">1</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="globalHistoryScrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="globalHistoryViewport">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<child>
<widget class="GtkDrawingArea" id="globalHistoryDrawingArea">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>

218
gtk/res/hotlist.glade Normal file
View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Wed Jul 29 03:02:21 2009 -->
<glade-interface>
<widget class="GtkWindow" id="wndHotlist">
<property name="title" translatable="yes">NetSurf Hotlist</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="default_width">600</property>
<property name="default_height">500</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_UTILITY</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">2</property>
<property name="spacing">2</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="export">
<property name="visible">True</property>
<property name="label" translatable="yes">_Export</property>
<property name="use_underline">True</property>
<accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="new_folder">
<property name="visible">True</property>
<property name="label" translatable="yes">New _folder</property>
<property name="use_underline">True</property>
<accelerator key="M" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="new_entry">
<property name="visible">True</property>
<property name="label" translatable="yes">New _entry</property>
<property name="use_underline">True</property>
<accelerator key="N" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu2">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="edit_selected">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="delete_selected">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Deletes selected nodes</property>
<property name="label" translatable="yes">_Delete</property>
<property name="use_underline">True</property>
<accelerator key="Delete" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="select_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_Select all</property>
<property name="use_underline">True</property>
<accelerator key="A" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="clear_selection">
<property name="visible">True</property>
<property name="label" translatable="yes">_Clear selection</property>
<property name="use_underline">True</property>
<accelerator key="U" modifiers="GDK_MOD1_MASK" signal="activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu4">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="expand">
<property name="visible">True</property>
<property name="label" translatable="yes">_Expand</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu5">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="expand_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_directories">
<property name="visible">True</property>
<property name="label" translatable="yes">_Directories</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="expand_addresses">
<property name="visible">True</property>
<property name="label" translatable="yes">Add_resses</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse">
<property name="visible">True</property>
<property name="label" translatable="yes">_Collapse</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu6">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="collapse_all">
<property name="visible">True</property>
<property name="label" translatable="yes">_All</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_directories">
<property name="visible">True</property>
<property name="label" translatable="yes">_Directories</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="collapse_addresses">
<property name="visible">True</property>
<property name="label" translatable="yes">Add_resses</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="launch">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Launches the selected addresses</property>
<property name="label" translatable="yes">_Launch</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="hotlistScrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="hotlistViewport">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<child>
<widget class="GtkDrawingArea" id="hotlistDrawingArea">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

1
gtk/res/icons Symbolic link
View File

@ -0,0 +1 @@
../../!NetSurf/Resources/Icons/

View File

@ -6,6 +6,8 @@
<property name="border_width">1</property>
<property name="title" translatable="yes">SSL certificate problem</property>
<property name="modal">True</property>
<property name="default_width">500</property>
<property name="default_height">250</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3">
@ -50,17 +52,22 @@
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<widget class="GtkScrolledWindow" id="SSLScrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkTextView" id="textview1">
<property name="height_request">200</property>
<widget class="GtkViewport" id="SSLViewport">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="text" translatable="yes">(not implemented)</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<child>
<widget class="GtkDrawingArea" id="SSLDrawingArea">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
</widget>
</child>
</widget>
</child>
</widget>

View File

@ -22,6 +22,7 @@
#include "riscos/gui.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/configure.h"
@ -42,16 +43,13 @@ static bool ro_gui_options_home_ok(wimp_w w);
bool ro_gui_options_home_initialise(wimp_w w)
{
int suggestions;
/* set the current values */
ro_gui_set_icon_string(w, HOME_URL_FIELD,
option_homepage_url ? option_homepage_url : "", true);
ro_gui_set_icon_selected_state(w, HOME_OPEN_STARTUP,
option_open_browser_at_startup);
global_history_get_recent(&suggestions);
ro_gui_set_icon_shaded_state(w,
HOME_URL_GRIGHT, (suggestions <= 0));
HOME_URL_GRIGHT, !ro_gui_url_suggest_prepare_menu());
/* initialise all functions for a newly created window */
ro_gui_wimp_event_register_menu_gright(w, HOME_URL_FIELD,

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -44,174 +45,243 @@
#include "utils/url.h"
#include "utils/utils.h"
static bool ro_gui_cookies_click(wimp_pointer *pointer);
static struct node *ro_gui_cookies_find(const char *url);
static void ro_gui_cookies_menu_prepare(wimp_w window, wimp_menu *menu);
static bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
static void ro_gui_cookies_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
/* The history window, toolbar and plot origins */
static wimp_w cookies_window;
struct tree *cookies_tree;
static bool cookies_init;
/* The RISC OS cookie window, toolbar and treeview data. */
static struct ro_cookies_window {
wimp_w window;
struct toolbar *toolbar;
ro_treeview *tv;
wimp_menu *menu;
} cookies_window;
/**
* Initialise cookies tree
* Pre-Initialise the cookies tree. This is called for things that
* need to be done at the gui_init() stage, such as loading templates.
*/
void ro_gui_cookies_initialise(void)
void ro_gui_cookies_preinitialise(void)
{
/* create our window */
cookies_window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(cookies_window,
/* Create our window. */
cookies_window.window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(cookies_window.window,
messages_get("Cookies"));
ro_gui_wimp_event_register_redraw_window(cookies_window,
ro_gui_tree_redraw);
ro_gui_wimp_event_register_open_window(cookies_window,
ro_gui_tree_open);
ro_gui_wimp_event_register_mouse_click(cookies_window,
ro_gui_cookies_click);
}
/* Create an empty tree */
cookies_tree = calloc(sizeof(struct tree), 1);
if (!cookies_tree) {
warn_user("NoMemory", 0);
return;
}
cookies_tree->root = tree_create_folder_node(NULL, "Root");
if (!cookies_tree->root) {
warn_user("NoMemory", 0);
free(cookies_tree);
cookies_tree = NULL;
return;
}
cookies_tree->root->expanded = true;
cookies_tree->handle = (int)cookies_window;
cookies_tree->movable = false;
cookies_tree->no_drag = true;
ro_gui_wimp_event_set_user_data(cookies_window,
cookies_tree);
ro_gui_wimp_event_register_keypress(cookies_window,
ro_gui_tree_keypress);
/**
* Initialise cookies tree, at the gui_init2() stage.
*/
/* Create our toolbar */
cookies_tree->toolbar = ro_gui_theme_create_toolbar(NULL,
void ro_gui_cookies_postinitialise(void)
{
/* Create our toolbar. */
cookies_window.toolbar = ro_gui_theme_create_toolbar(NULL,
THEME_COOKIES_TOOLBAR);
if (cookies_tree->toolbar)
ro_gui_theme_attach_toolbar(cookies_tree->toolbar,
cookies_window);
if (cookies_window.toolbar)
ro_gui_theme_attach_toolbar(cookies_window.toolbar,
cookies_window.window);
cookies_init = true;
urldb_iterate_cookies(cookies_update);
cookies_init = false;
tree_initialise(cookies_tree);
}
/* Create the treeview with the window and toolbar. */
/**
* Respond to a mouse click
*
* \param pointer the pointer state
* \return true to indicate click handled
*/
bool ro_gui_cookies_click(wimp_pointer *pointer)
{
ro_gui_tree_click(pointer, cookies_tree);
if (pointer->buttons == wimp_CLICK_MENU)
ro_gui_menu_create(cookies_menu, pointer->pos.x,
pointer->pos.y, pointer->w);
else
ro_gui_menu_prepare_action(pointer->w, TREE_SELECTION, false);
return true;
}
/**
* Perform cookie addition
*
* \param data Cookie data for a domain, or NULL
* \return true (for urldb_iterate_entries)
*/
bool cookies_update(const char *domain, const struct cookie_data *data)
{
struct node *parent;
struct node *node = NULL;
struct node *child;
struct node *add;
const struct cookie_data *cookie = NULL;
bool expanded;
assert(domain);
/* check if we're a domain, and add get the first cookie */
if (data)
for (cookie = data; cookie->prev; cookie = cookie->prev);
if (!cookies_init) {
node = ro_gui_cookies_find(domain);
if (node) {
/* mark as deleted so we don't remove the cookies */
expanded = node->expanded;
for (child = node->child; child; child = child->next)
child->deleted = true;
if (node->child)
tree_delete_node(cookies_tree, node->child,
true);
/* deleting will have contracted our node */
node->expanded = expanded;
}
if (!data) {
if (!node)
return true;
tree_delete_node(cookies_tree, node, false);
tree_handle_node_changed(cookies_tree,
cookies_tree->root, true, false);
return true;
}
cookies_window.tv = ro_treeview_create(cookies_window.window,
cookies_window.toolbar, cookies_get_tree_flags());
if (cookies_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
if (!node) {
for (parent = cookies_tree->root->child; parent;
parent = parent->next) {
if (strcmp(domain, parent->data.text) == 0)
break;
}
if (!parent) {
node = tree_create_folder_node(cookies_tree->root,
domain);
} else {
node = parent;
/* Initialise the cookies into the tree. */
cookies_initialise(ro_treeview_get_tree(cookies_window.tv));
/* Build the cookies window menu. */
static const struct ns_menu cookies_definition = {
"Cookies", {
{ "Cookies", NO_ACTION, 0 },
{ "Cookies.Expand", TREE_EXPAND_ALL, 0 },
{ "Cookies.Expand.All", TREE_EXPAND_ALL, 0 },
{ "Cookies.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "Cookies.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "Cookies.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "Cookies.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "Cookies.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "Cookies.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "Cookies.Toolbars", NO_ACTION, 0 },
{ "_Cookies.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "Cookies.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
};
cookies_window.menu = ro_gui_menu_define_menu(&cookies_definition);
ro_gui_wimp_event_register_window_menu(cookies_window.window,
cookies_window.menu, ro_gui_cookies_menu_prepare,
ro_gui_cookies_menu_select, NULL,
ro_gui_cookies_menu_warning, false);
}
/**
* \TODO - Open the cookies window.
*
*/
void ro_gui_cookies_open(void)
{
tree_set_redraw(ro_treeview_get_tree(cookies_window.tv), true);
if (!ro_gui_dialog_open_top(cookies_window.window,
cookies_window.toolbar, 600, 800)) {
ro_treeview_set_origin(cookies_window.tv, 0,
-(ro_gui_theme_toolbar_height(
cookies_window.toolbar)));
}
if (!node)
}
/**
* Prepare the cookies menu for opening
*
* \param window The window owning the menu.
* \param *menu The menu about to be opened.
*/
void ro_gui_cookies_menu_prepare(wimp_w window, wimp_menu *menu)
{
bool selection;
selection = ro_treeview_has_selection(cookies_window.tv);
ro_gui_menu_set_entry_shaded(cookies_window.menu, TREE_SELECTION,
!selection);
ro_gui_menu_set_entry_shaded(cookies_window.menu, TREE_CLEAR_SELECTION,
!selection);
ro_gui_menu_set_entry_shaded(cookies_window.menu, TOOLBAR_BUTTONS,
(cookies_window.toolbar == NULL ||
cookies_window.toolbar->editor));
ro_gui_menu_set_entry_ticked(cookies_window.menu, TOOLBAR_BUTTONS,
(cookies_window.toolbar != NULL &&
(cookies_window.toolbar->display_buttons ||
(cookies_window.toolbar->editor))));
ro_gui_menu_set_entry_shaded(cookies_window.menu, TOOLBAR_EDIT,
cookies_window.toolbar == NULL);
ro_gui_menu_set_entry_ticked(cookies_window.menu, TOOLBAR_EDIT,
(cookies_window.toolbar != NULL &&
cookies_window.toolbar->editor));
}
/**
* Handle submenu warnings for the cookies menu
*
* \param window The window owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
void ro_gui_cookies_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
/* Do nothing */
}
/**
* Handle selections from the cookies menu
*
* \param window The window owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
switch (action) {
case TREE_EXPAND_ALL:
cookies_expand_all();
return true;
node->editable = false;
case TREE_EXPAND_FOLDERS:
cookies_expand_domains();
return true;
case TREE_EXPAND_LINKS:
cookies_expand_cookies();
return true;
case TREE_COLLAPSE_ALL:
cookies_collapse_all();
return true;
case TREE_COLLAPSE_FOLDERS:
cookies_collapse_domains();
return true;
case TREE_COLLAPSE_LINKS:
cookies_collapse_cookies();
return true;
case TREE_SELECTION_DELETE:
cookies_delete_selected();
return true;
case TREE_SELECT_ALL:
cookies_select_all();
return true;
case TREE_CLEAR_SELECTION:
cookies_clear_selection();
return true;
default:
return false;
}
for (; cookie; cookie = cookie->next) {
add = tree_create_cookie_node(node, cookie);
if (add && !cookies_init)
tree_handle_node_changed(cookies_tree, add,
true, false);
}
if (!cookies_init) {
tree_handle_node_changed(cookies_tree, node,
true, false);
tree_redraw_area(cookies_tree,
node->box.x - NODE_INSTEP,
0, NODE_INSTEP, 16384);
}
return true;
return false;
}
/**
* Find an entry in the cookie tree
*
* \param url The URL to find
* \return Pointer to node, or NULL if not found
* Update the theme details of the cookies window.
*/
struct node *ro_gui_cookies_find(const char *url)
{
struct node *node;
for (node = cookies_tree->root->child; node; node = node->next) {
if (!strcmp(url, node->data.text))
return node;
}
return NULL;
void ro_gui_cookies_update_theme(void)
{
ro_treeview_update_theme(cookies_window.tv);
}
/**
* Check if a particular window handle is the cookies window
*
* \param window the window in question
* \return true if this window is the cookies
*/
bool ro_gui_cookies_check_window(wimp_w window)
{
/* SF if (cookies_window.w == window)
return true;
else*/
return false;
}
/**
* Check if a particular menu handle is the cookies menu
*
* \param *menu The menu in question.
* \return true if this menu is the cookies menu
*/
bool ro_gui_cookies_check_menu(wimp_menu *menu)
{
if (cookies_window.menu == menu)
return true;
else
return false;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -23,6 +24,13 @@
#ifndef _NETSURF_RISCOS_COOKIES_H_
#define _NETSURF_RISCOS_COOKIES_H_
void ro_gui_cookies_initialise(void);
void ro_gui_cookies_preinitialise(void);
void ro_gui_cookies_postinitialise(void);
bool ro_gui_cookies_check_window(wimp_w window);
bool ro_gui_cookies_check_menu(wimp_menu *menu);
void ro_gui_cookies_open(void);
void ro_gui_cookies_update_theme(void);
#endif

View File

@ -39,11 +39,14 @@
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/sslcert.h"
#include "riscos/theme.h"
#include "riscos/url_complete.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/wimputils.h"
@ -106,18 +109,6 @@ void ro_gui_dialog_init(void)
/* 401 login window */
ro_gui_401login_init();
/* certificate verification window */
ro_gui_cert_init();
/* hotlist window */
ro_gui_hotlist_initialise();
/* global history window */
ro_gui_global_history_initialise();
/* cookies window */
ro_gui_cookies_initialise();
/* theme installation */
dialog_theme_install = ro_gui_dialog_create("theme_inst");
ro_gui_wimp_event_register_cancel(dialog_theme_install,
@ -150,24 +141,6 @@ void ro_gui_dialog_init(void)
dialog_objinfo = ro_gui_dialog_create("objectinfo");
ro_gui_wimp_event_set_help_prefix(dialog_objinfo, "HelpObjInfo");
/* hotlist folder editing */
dialog_folder = ro_gui_dialog_create("new_folder");
ro_gui_wimp_event_register_text_field(dialog_folder, ICON_FOLDER_NAME);
ro_gui_wimp_event_register_cancel(dialog_folder, ICON_FOLDER_CANCEL);
ro_gui_wimp_event_register_ok(dialog_folder, ICON_FOLDER_OK,
ro_gui_hotlist_dialog_apply);
ro_gui_wimp_event_set_help_prefix(dialog_folder, "HelpHotFolder");
/* hotlist entry editing */
dialog_entry = ro_gui_dialog_create("new_entry");
ro_gui_wimp_event_register_text_field(dialog_entry, ICON_ENTRY_NAME);
ro_gui_wimp_event_register_menu_gright(dialog_entry, ICON_ENTRY_URL,
ICON_ENTRY_RECENT, url_suggest_menu);
ro_gui_wimp_event_register_cancel(dialog_entry, ICON_ENTRY_CANCEL);
ro_gui_wimp_event_register_ok(dialog_entry, ICON_ENTRY_OK,
ro_gui_hotlist_dialog_apply);
ro_gui_wimp_event_set_help_prefix(dialog_entry, "HelpHotEntry");
/* save as */
dialog_saveas = ro_gui_saveas_create("saveas");
ro_gui_wimp_event_register_button(dialog_saveas, ICON_SAVE_ICON,
@ -204,6 +177,22 @@ void ro_gui_dialog_init(void)
ro_gui_wimp_event_register_ok(dialog_zoom, ICON_ZOOM_OK,
ro_gui_dialog_zoom_apply);
ro_gui_wimp_event_set_help_prefix(dialog_zoom, "HelpScaleView");
/* Treeview initialisation has moved to the end, to allow any
* associated dialogues to be set up first.
*/
/* certificate verification window */
ro_gui_cert_preinitialise();
/* hotlist window */
ro_gui_hotlist_preinitialise();
/* global history window */
ro_gui_global_history_preinitialise();
/* cookies window */
ro_gui_cookies_preinitialise();
}
@ -638,15 +627,25 @@ void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w) {
*/
void ro_gui_dialog_close_persistent(wimp_w parent) {
int i;
int i;
wimp_w w;
/* Check our mappings
*/
/* Check our mappings.
*
* The window handle is copied into w before proceeding, as
* ro_gui_dialog_close() will NULL persistent_dialog[i].dialog as
* part of the closing process. This would mean that the subsequent
* event dispatch would fail. (These events are logged to allow
* side effects to be investigated -- this code hasn't worked before).
*/
for (i = 0; i < MAX_PERSISTENT; i++) {
if (persistent_dialog[i].parent == parent &&
persistent_dialog[i].dialog != NULL) {
ro_gui_dialog_close(persistent_dialog[i].dialog);
ro_gui_wimp_event_close_window(persistent_dialog[i].dialog);
w = persistent_dialog[i].dialog;
ro_gui_dialog_close(w);
if (ro_gui_wimp_event_close_window(w))
LOG(("Persistent dialog close event: 0x%x",
(unsigned) w));
persistent_dialog[i].parent = NULL;
persistent_dialog[i].dialog = NULL;
}
@ -710,7 +709,6 @@ bool ro_gui_dialog_openurl_apply(wimp_w w) {
res = url_normalize(url, &url2);
if (res == URL_FUNC_OK) {
browser_window_create(url2, 0, 0, true, false);
global_history_add_recent(url2);
free(url2);
return true;
}
@ -724,10 +722,8 @@ bool ro_gui_dialog_openurl_apply(wimp_w w) {
void ro_gui_dialog_prepare_open_url(void)
{
int suggestions;
ro_gui_set_icon_string(dialog_openurl, ICON_OPENURL_URL, "", true);
global_history_get_recent(&suggestions);
ro_gui_set_icon_shaded_state(dialog_openurl,
ICON_OPENURL_MENU, (suggestions <= 0));
ICON_OPENURL_MENU, !ro_gui_url_suggest_prepare_menu());
ro_gui_wimp_event_memorise(dialog_openurl);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -29,12 +30,14 @@
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
#include "content/urldb.h"
#include "desktop/history_global_core.h"
#include "desktop/tree.h"
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/theme.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
@ -44,401 +47,260 @@
#include "utils/url.h"
#include "utils/utils.h"
#define MAXIMUM_URL_LENGTH 1024
#define MAXIMUM_BASE_NODES 16
static void ro_gui_global_history_menu_prepare(wimp_w window, wimp_menu *menu);
static bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
static void ro_gui_global_history_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
static struct node *global_history_base_node[MAXIMUM_BASE_NODES];
static int global_history_base_node_time[MAXIMUM_BASE_NODES];
static int global_history_base_node_count = 0;
/* The RISC OS global history window, toolbar and treeview data */
static char *global_history_recent_url[GLOBAL_HISTORY_RECENT_URLS];
static int global_history_recent_count = 0;
static bool global_history_init;
static bool ro_gui_global_history_click(wimp_pointer *pointer);
static void ro_gui_global_history_initialise_nodes(void);
static void ro_gui_global_history_initialise_node(const char *title,
time_t base, int days_back);
static struct node *ro_gui_global_history_find(const char *url);
static bool global_history_add_internal(const char *url,
const struct url_data *data);
/* The history window, toolbar and plot origins */
static wimp_w global_history_window;
struct tree *global_history_tree;
static struct ro_global_history_window {
wimp_w window;
struct toolbar *toolbar;
ro_treeview *tv;
wimp_menu *menu;
} global_history_window;
/**
* Initialise global history tree
* Pre-Initialise the global history tree. This is called for things that
* need to be done at the gui_init() stage, such as loading templates.
*/
void ro_gui_global_history_initialise(void)
{
char s[MAXIMUM_URL_LENGTH];
FILE *fp;
/* create our window */
global_history_window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(global_history_window,
void ro_gui_global_history_preinitialise(void)
{
/* Create our window. */
global_history_window.window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(global_history_window.window,
messages_get("GlobalHistory"));
ro_gui_wimp_event_register_redraw_window(global_history_window,
ro_gui_tree_redraw);
ro_gui_wimp_event_register_open_window(global_history_window,
ro_gui_tree_open);
ro_gui_wimp_event_register_mouse_click(global_history_window,
ro_gui_global_history_click);
}
/* Create an empty tree */
global_history_tree = calloc(sizeof(struct tree), 1);
if (!global_history_tree) {
warn_user("NoMemory", 0);
return;
}
global_history_tree->root = tree_create_folder_node(NULL, "Root");
if (!global_history_tree->root) {
warn_user("NoMemory", 0);
free(global_history_tree);
global_history_tree = NULL;
return;
}
global_history_tree->root->expanded = true;
ro_gui_global_history_initialise_nodes();
global_history_tree->handle = (int)global_history_window;
global_history_tree->movable = false;
ro_gui_wimp_event_set_user_data(global_history_window,
global_history_tree);
ro_gui_wimp_event_register_keypress(global_history_window,
ro_gui_tree_keypress);
/**
* Initialise global history tree, at the gui_init2() stage.
*/
/* Create our toolbar */
global_history_tree->toolbar = ro_gui_theme_create_toolbar(NULL,
void ro_gui_global_history_postinitialise(void)
{
/* Create our toolbar. */
global_history_window.toolbar = ro_gui_theme_create_toolbar(NULL,
THEME_HISTORY_TOOLBAR);
if (global_history_tree->toolbar)
ro_gui_theme_attach_toolbar(global_history_tree->toolbar,
global_history_window);
if (global_history_window.toolbar)
ro_gui_theme_attach_toolbar(global_history_window.toolbar,
global_history_window.window);
/* load recent URLs */
fp = fopen(option_recent_path, "r");
if (!fp)
LOG(("Failed to open file '%s' for reading",
option_recent_path));
else {
while (fgets(s, MAXIMUM_URL_LENGTH, fp)) {
if (s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = '\0';
global_history_add_recent(s);
/* Create the treeview with the window and toolbar. */
global_history_window.tv =
ro_treeview_create(global_history_window.window,
global_history_window.toolbar,
history_global_get_tree_flags());
if (global_history_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
/* Initialise the global history into the tree. */
history_global_initialise(
ro_treeview_get_tree(global_history_window.tv));
/* Build the global history window menu. */
static const struct ns_menu global_history_definition = {
"History", {
{ "History", NO_ACTION, 0 },
{ "_History.Export", HISTORY_EXPORT, &dialog_saveas },
{ "History.Expand", TREE_EXPAND_ALL, 0 },
{ "History.Expand.All", TREE_EXPAND_ALL, 0 },
{ "History.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "History.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "History.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "History.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "History.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "History.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "History.Toolbars", NO_ACTION, 0 },
{ "_History.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "History.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
{ "Selection.Launch", TREE_SELECTION_LAUNCH, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
fclose(fp);
}
};
global_history_window.menu = ro_gui_menu_define_menu(
&global_history_definition);
global_history_init = true;
urldb_iterate_entries(global_history_add_internal);
global_history_init = false;
tree_initialise(global_history_tree);
ro_gui_wimp_event_register_window_menu(global_history_window.window,
global_history_window.menu,
ro_gui_global_history_menu_prepare,
ro_gui_global_history_menu_select, NULL,
ro_gui_global_history_menu_warning, false);
}
/**
* Initialises the base nodes
* Open the global history window.
*/
void ro_gui_global_history_initialise_nodes(void)
void ro_gui_global_history_open(void)
{
struct tm *full_time;
time_t t;
int weekday;
int i;
tree_set_redraw(ro_treeview_get_tree(global_history_window.tv), true);
/* get the current time */
t = time(NULL);
if (t == -1)
return;
/* get the time at the start of today */
full_time = localtime(&t);
weekday = full_time->tm_wday;
full_time->tm_sec = 0;
full_time->tm_min = 0;
full_time->tm_hour = 0;
t = mktime(full_time);
if (t == -1)
return;
ro_gui_global_history_initialise_node(messages_get("DateToday"), t, 0);
if (weekday > 0)
ro_gui_global_history_initialise_node(
messages_get("DateYesterday"), t, -1);
for (i = 2; i <= weekday; i++)
ro_gui_global_history_initialise_node(NULL, t, -i);
ro_gui_global_history_initialise_node(messages_get("Date1Week"),
t, -weekday - 7);
ro_gui_global_history_initialise_node(messages_get("Date2Week"),
t, -weekday - 14);
ro_gui_global_history_initialise_node(messages_get("Date3Week"),
t, -weekday - 21);
}
/**
* Create and initialise a node
*/
void ro_gui_global_history_initialise_node(const char *title,
time_t base, int days_back)
{
struct tm *full_time;
char buffer[64];
struct node *node;
base += days_back * 60 * 60 * 24;
if (!title) {
full_time = localtime(&base);
strftime((char *)&buffer, (size_t)64, "%A", full_time);
node = tree_create_folder_node(NULL, buffer);
} else
node = tree_create_folder_node(NULL, title);
if (!node)
return;
node->retain_in_memory = true;
node->deleted = true;
node->editable = false;
global_history_base_node[global_history_base_node_count] = node;
global_history_base_node_time[global_history_base_node_count] = base;
global_history_base_node_count++;
}
/**
* Saves the global history's recent URL data.
*/
void ro_gui_global_history_save(void)
{
FILE *fp;
int i;
/* save recent URLs */
fp = fopen(option_recent_save, "w");
if (!fp)
LOG(("Failed to open file '%s' for writing",
option_recent_save));
else {
for (i = global_history_recent_count - 1; i >= 0; i--)
if (strlen(global_history_recent_url[i]) <
MAXIMUM_URL_LENGTH)
fprintf(fp, "%s\n",
global_history_recent_url[i]);
fclose(fp);
if (!ro_gui_dialog_open_top(global_history_window.window,
global_history_window.toolbar, 600, 800)) {
ro_treeview_set_origin(global_history_window.tv, 0,
-(ro_gui_theme_toolbar_height(
global_history_window.toolbar)));
}
}
/**
* Respond to a mouse click
* Prepare the global history menu for opening
*
* \param pointer the pointer state
* \return true to indicate click handled
* \param window The window owning the menu.
* \param *menu The menu about to be opened.
*/
bool ro_gui_global_history_click(wimp_pointer *pointer)
void ro_gui_global_history_menu_prepare(wimp_w window, wimp_menu *menu)
{
ro_gui_tree_click(pointer, global_history_tree);
if (pointer->buttons == wimp_CLICK_MENU)
ro_gui_menu_create(global_history_menu, pointer->pos.x,
pointer->pos.y, pointer->w);
else
ro_gui_menu_prepare_action(pointer->w, TREE_SELECTION, false);
return true;
}
bool selection;
selection = ro_treeview_has_selection(global_history_window.tv);
/**
* Adds to the global history
*
* \param url The URL to add
*/
void global_history_add(const char *url)
{
const struct url_data *data;
ro_gui_menu_set_entry_shaded(global_history_window.menu,
TREE_SELECTION, !selection);
ro_gui_menu_set_entry_shaded(global_history_window.menu,
TREE_CLEAR_SELECTION, !selection);
data = urldb_get_url_data(url);
if (!data)
return;
ro_gui_menu_set_entry_shaded(global_history_window.menu,
TOOLBAR_BUTTONS,
(global_history_window.toolbar == NULL ||
global_history_window.toolbar->editor));
ro_gui_menu_set_entry_ticked(global_history_window.menu,
TOOLBAR_BUTTONS,
(global_history_window.toolbar != NULL &&
(global_history_window.toolbar->display_buttons ||
(global_history_window.toolbar->editor))));
global_history_add_internal(url, data);
ro_gui_menu_set_entry_shaded(global_history_window.menu, TOOLBAR_EDIT,
global_history_window.toolbar == NULL);
ro_gui_menu_set_entry_ticked(global_history_window.menu, TOOLBAR_EDIT,
(global_history_window.toolbar != NULL &&
global_history_window.toolbar->editor));
ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML,
NULL, NULL, NULL, NULL);
}
/**
* Internal routine to actually perform global history addition
* Handle submenu warnings for the global_hostory menu
*
* \param url The URL to add
* \param data URL data associated with URL
* \return true (for urldb_iterate_entries)
* \param window The window owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
bool global_history_add_internal(const char *url,
const struct url_data *data)
void ro_gui_global_history_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
int i, j;
struct node *parent = NULL;
struct node *link;
struct node *node;
bool before = false;
int visit_date;
/* Do nothing */
}
assert(url && data);
/**
* Handle selections from the global history menu
*
* \param window The window owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
visit_date = data->last_visit;
/* find parent node */
for (i = 0; i < global_history_base_node_count; i++) {
if (global_history_base_node_time[i] <= visit_date) {
parent = global_history_base_node[i];
break;
}
}
/* the entry is too old to care about */
if (!parent)
bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
switch (action) {
case HISTORY_EXPORT:
ro_gui_dialog_open_persistent(window, dialog_saveas, true);
return true;
if (parent->deleted) {
/* parent was deleted, so find place to insert it */
link = global_history_tree->root;
for (j = global_history_base_node_count - 1; j >= 0; j--) {
if (!global_history_base_node[j]->deleted &&
global_history_base_node_time[j] >
global_history_base_node_time[i]) {
link = global_history_base_node[j];
before = true;
break;
}
}
tree_set_node_selected(global_history_tree,
parent, false);
tree_set_node_expanded(global_history_tree,
parent, false);
tree_link_node(link, parent, before);
if (!global_history_init) {
tree_recalculate_node(global_history_tree, parent, true);
tree_recalculate_node_positions(global_history_tree,
global_history_tree->root);
tree_redraw_area(global_history_tree,
0, 0, 16384, 16384);
}
case TREE_EXPAND_ALL:
history_global_expand_all();
return true;
case TREE_EXPAND_FOLDERS:
history_global_expand_directories();
return true;
case TREE_EXPAND_LINKS:
history_global_expand_addresses();
return true;
case TREE_COLLAPSE_ALL:
history_global_collapse_all();
return true;
case TREE_COLLAPSE_FOLDERS:
history_global_collapse_directories();
return true;
case TREE_COLLAPSE_LINKS:
history_global_collapse_addresses();
return true;
case TREE_SELECTION_LAUNCH:
history_global_launch_selected();
return true;
case TREE_SELECTION_DELETE:
history_global_delete_selected();
return true;
case TREE_SELECT_ALL:
history_global_select_all();
return true;
case TREE_CLEAR_SELECTION:
history_global_clear_selection();
return true;
default:
return false;
}
/* find any previous occurance */
if (!global_history_init) {
node = ro_gui_global_history_find(url);
if (node) {
/* \todo: calculate old/new positions and redraw
* only the relevant portion */
tree_redraw_area(global_history_tree,
0, 0, 16384, 16384);
tree_update_URL_node(node, url, data);
tree_delink_node(node);
tree_link_node(parent, node, false);
tree_handle_node_changed(global_history_tree,
node, false, true);
/* ro_gui_tree_scroll_visible(hotlist_tree,
&node->data);
*/ return true;
}
}
/* Add the node at the bottom */
node = tree_create_URL_node_shared(parent, url, data);
if ((!global_history_init) && (node)) {
tree_redraw_area(global_history_tree,
node->box.x - NODE_INSTEP,
0, NODE_INSTEP, 16384);
tree_handle_node_changed(global_history_tree, node,
true, false);
}
return true;
return false;
}
/**
* Find an entry in the global history
*
* \param url The URL to find
* \return Pointer to node, or NULL if not found
* Update the theme details of the global history window.
*/
struct node *ro_gui_global_history_find(const char *url)
void ro_gui_global_history_update_theme(void)
{
int i;
struct node *node;
struct node_element *element;
for (i = 0; i < global_history_base_node_count; i++) {
if (!global_history_base_node[i]->deleted) {
for (node = global_history_base_node[i]->child;
node; node = node->next) {
element = tree_find_element(node,
TREE_ELEMENT_URL);
if ((element) && !strcmp(url, element->text))
return node;
}
}
}
return NULL;
ro_treeview_update_theme(global_history_window.tv);
}
/**
* Adds an URL to the recently used list
* Check if a particular window handle is the global history window
*
* \param url the URL to add (copied)
* \param window the window in question
* \return true if this window is the global history
*/
void global_history_add_recent(const char *url)
bool ro_gui_global_history_check_window(wimp_w window)
{
int i;
int j = -1;
char *current;
/* try to find a string already there */
for (i = 0; i < global_history_recent_count; i++)
if (global_history_recent_url[i] &&
!strcmp(global_history_recent_url[i], url))
j = i;
/* already at head of list */
if (j == 0)
return;
if (j < 0) {
/* add to head of list */
free(global_history_recent_url[
GLOBAL_HISTORY_RECENT_URLS - 1]);
memmove(&global_history_recent_url[1],
&global_history_recent_url[0],
(GLOBAL_HISTORY_RECENT_URLS - 1) *
sizeof(char *));
global_history_recent_url[0] = strdup(url);
global_history_recent_count++;
if (global_history_recent_count > GLOBAL_HISTORY_RECENT_URLS)
global_history_recent_count =
GLOBAL_HISTORY_RECENT_URLS;
if (global_history_recent_count == 1)
ro_gui_window_prepare_navigate_all();
} else {
/* move to head of list */
current = global_history_recent_url[j];
for (i = j; i > 0; i--)
global_history_recent_url[i] =
global_history_recent_url[i - 1];
global_history_recent_url[0] = current;
}
/* if (global_history_window.w == window)
return true;
else*/
return false;
}
/**
* Gets details of the currently used URL list.
* Check if a particular menu handle is the global history menu
*
* \param count set to the current number of entries in the URL array on exit
* \return the current URL array
* \param *menu The menu in question.
* \return true if this menu is the global history menu
*/
char **global_history_get_recent(int *count)
bool ro_gui_global_history_check_menu(wimp_menu *menu)
{
*count = global_history_recent_count;
return global_history_recent_url;
if (global_history_window.menu == menu)
return true;
else
return false;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -23,10 +24,13 @@
#ifndef _NETSURF_RISCOS_GLOBALHISTORY_H_
#define _NETSURF_RISCOS_GLOBALHISTORY_H_
#define GLOBAL_HISTORY_RECENT_URLS 16
void ro_gui_global_history_initialise(void);
void ro_gui_global_history_preinitialise(void);
void ro_gui_global_history_postinitialise(void);
void ro_gui_global_history_open(void);
void ro_gui_global_history_save(void);
void ro_gui_global_history_update_theme(void);
bool ro_gui_global_history_check_window(wimp_w window);
bool ro_gui_global_history_check_menu(wimp_menu *menu);
#endif

View File

@ -55,20 +55,26 @@
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/cookies.h"
#include "desktop/gui.h"
#include "desktop/history_global_core.h"
#include "desktop/hotlist.h"
#include "desktop/netsurf.h"
#include "desktop/options.h"
#include "desktop/save_complete.h"
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
#include "render/box.h"
#include "render/font.h"
#include "render/html.h"
#include "riscos/bitmap.h"
#include "riscos/buffer.h"
#include "riscos/cookies.h"
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/help.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/options.h"
@ -78,6 +84,7 @@
#include "riscos/print.h"
#include "riscos/query.h"
#include "riscos/save.h"
#include "riscos/sslcert.h"
#include "riscos/textselection.h"
#include "riscos/theme.h"
#include "riscos/treeview.h"
@ -184,7 +191,7 @@ static struct {
} prev_sigs;
/** Accepted wimp user messages. */
static ns_wimp_message_list task_messages = {
static ns_wimp_message_list task_messages = {
message_HELP_REQUEST,
{
message_DATA_SAVE,
@ -347,6 +354,8 @@ static void gui_init(int argc, char** argv)
option_theme_path = strdup("NetSurf:Themes");
if (!option_theme_save)
option_theme_save = strdup(CHOICES_PREFIX "Themes");
if (!option_tree_icons_dir)
option_tree_icons_dir = strdup("NetSurf:Resources.Icons");
if (!option_theme || ! option_toolbar_browser ||
!option_toolbar_hotlist || !option_toolbar_history ||
@ -355,7 +364,7 @@ static void gui_init(int argc, char** argv)
!option_url_save || !option_hotlist_path ||
!option_hotlist_save || !option_recent_path ||
!option_recent_save || !option_theme_path ||
!option_theme_save)
!option_theme_save || !option_tree_icons_dir)
die("Failed initialising string options");
/* Create our choices directories */
@ -394,7 +403,7 @@ static void gui_init(int argc, char** argv)
default_stylesheet_url = strdup("file:///NetSurf:/Resources/CSS");
quirks_stylesheet_url = strdup("file:///NetSurf:/Resources/Quirks");
adblock_stylesheet_url = strdup("file:///NetSurf:/Resources/AdBlock");
if (!default_stylesheet_url || !quirks_stylesheet_url ||
if (!default_stylesheet_url || !quirks_stylesheet_url ||
!adblock_stylesheet_url)
die("Failed initialising string constants.");
@ -479,9 +488,6 @@ static void gui_init(int argc, char** argv)
/* Done with the templates file */
wimp_close_template();
/* Initialise tree views (must be after UI sprites are loaded) */
ro_gui_tree_initialise();
/* Create Iconbar icon */
ro_gui_icon_bar_create();
@ -670,6 +676,21 @@ static void gui_init2(int argc, char** argv)
char *url = 0;
bool open_window = option_open_browser_at_startup;
/* Complete initialisation of the treeview modules. */
/* certificate verification window */
ro_gui_cert_postinitialise();
/* hotlist window */
ro_gui_hotlist_postinitialise();
/* global history window */
ro_gui_global_history_postinitialise();
/* cookies window */
ro_gui_cookies_postinitialise();
/* parse command-line arguments */
if (argc == 2) {
LOG(("parameters: '%s'", argv[1]));
@ -781,8 +802,9 @@ void gui_quit(void)
urldb_save_cookies(option_cookie_jar);
urldb_save(option_url_save);
ro_gui_window_quit();
ro_gui_global_history_save();
ro_gui_hotlist_save();
history_global_cleanup();
cookies_cleanup();
hotlist_cleanup(option_hotlist_save);
ro_gui_saveas_quit();
rufl_quit();
free(gui_sprites);
@ -1109,6 +1131,9 @@ void ro_gui_null_reason_code(void)
// break;
default:
if (ro_gui_hotlist_check_window(gui_track_wimp_w))
ro_treeview_mouse_at(gui_track_wimp_w,
&pointer);
if (gui_track_wimp_w == history_window)
ro_gui_history_mouse_at(&pointer);
if (gui_track_wimp_w == dialog_url_complete)
@ -1203,8 +1228,10 @@ void ro_gui_pointer_entering_window(wimp_entering *entering)
default:
gui_track_wimp_w = entering->w;
gui_track_gui_window = ro_gui_window_lookup(entering->w);
gui_track = gui_track_gui_window || gui_track_wimp_w == history_window ||
gui_track_wimp_w == dialog_url_complete;
gui_track = gui_track_gui_window ||
gui_track_wimp_w == history_window ||
gui_track_wimp_w == dialog_url_complete ||
ro_gui_hotlist_check_window(gui_track_wimp_w);
break;
}
}
@ -1275,11 +1302,11 @@ void ro_gui_drag_end(wimp_dragged *drag)
break;
case GUI_DRAG_TREE_SELECT:
ro_gui_tree_selection_drag_end(drag);
// ro_gui_tree_selection_drag_end(drag);
break;
case GUI_DRAG_TREE_MOVE:
ro_gui_tree_move_drag_end(drag);
// ro_gui_tree_move_drag_end(drag);
break;
case GUI_DRAG_TOOLBAR_CONFIG:
@ -1485,12 +1512,7 @@ void ro_msg_dataload(wimp_message *message)
char *url = 0;
char *title = NULL;
struct gui_window *g;
struct node *node;
struct node *link;
os_error *error;
int x, y;
bool before;
const struct url_data *data;
g = ro_gui_window_lookup(message->data.data_xfer.w);
if (g) {
@ -1551,28 +1573,9 @@ void ro_msg_dataload(wimp_message *message)
if (g) {
browser_window_go(g->bw, url, 0, true);
} else if ((hotlist_tree) && ((wimp_w)hotlist_tree->handle ==
message->data.data_xfer.w)) {
data = urldb_get_url_data(url);
if (!data) {
urldb_add_url(url);
urldb_set_url_persistence(url, true);
data = urldb_get_url_data(url);
}
if (data) {
ro_gui_tree_get_tree_coordinates(hotlist_tree,
message->data.data_xfer.pos.x,
message->data.data_xfer.pos.y,
&x, &y);
link = tree_get_link_details(hotlist_tree, x, y, &before);
node = tree_create_URL_node(NULL, url, data, title);
tree_link_node(link, node, before);
tree_handle_node_changed(hotlist_tree, node, false, true);
tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, 0,
NODE_INSTEP, 16384);
if ((!title) && (!data->title))
ro_gui_tree_start_edit(hotlist_tree, &node->data, NULL);
}
// } else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) {
// /* Drop URL into hotlist */
// ro_gui_hotlist_url_drop(message, url);
} else {
browser_window_create(url, 0, 0, true, false);
}

View File

@ -64,7 +64,6 @@ extern bool gui_redraw_debug;
extern osspriteop_area *gui_sprites;
extern bool dialog_folder_add, dialog_entry_add, hotlist_insert;
extern bool print_active, print_text_black;
extern struct tree *hotlist_tree, *global_history_tree, *cookies_tree;
typedef enum { GUI_DRAG_NONE, GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE,
GUI_DRAG_SAVE, GUI_DRAG_SCROLL, GUI_DRAG_STATUS_RESIZE,
@ -136,10 +135,6 @@ bool ro_gui_download_prequit(void);
/* in 401login.c */
void ro_gui_401login_init(void);
/* in sslcert.c */
void ro_gui_cert_init(void);
void ro_gui_cert_open(struct tree *tree, struct node *node);
/* in window.c */
void ro_gui_window_quit(void);
/* void ro_gui_window_close_all(void); */
@ -161,7 +156,10 @@ void ro_gui_window_process_reformats(void);
void ro_gui_window_default_options(struct browser_window *bw);
void ro_gui_window_redraw_all(void);
void ro_gui_window_prepare_navigate_all(void);
browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons);
browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
wimp_icon_flags type);
browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
wimp_icon_flags type);
bool ro_gui_shift_pressed(void);
bool ro_gui_ctrl_pressed(void);
bool ro_gui_alt_pressed(void);
@ -178,13 +176,6 @@ void ro_gui_history_open(struct browser_window *bw, struct history *history,
bool pointer);
void ro_gui_history_mouse_at(wimp_pointer *pointer);
/* in hotlist.c */
void ro_gui_hotlist_initialise(void);
void ro_gui_hotlist_save(void);
void ro_gui_hotlist_prepare_folder_dialog(struct node *node);
void ro_gui_hotlist_prepare_entry_dialog(struct node *node);
bool ro_gui_hotlist_dialog_apply(wimp_w w);
/* in filetype.c */
int ro_content_filetype(struct hlcache_handle *c);
int ro_content_filetype_from_type(content_type type);

View File

@ -28,7 +28,10 @@
#include "oslib/taskmanager.h"
#include "oslib/wimp.h"
#include "desktop/tree.h"
#include "riscos/cookies.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/hotlist.h"
#include "riscos/help.h"
#include "riscos/menus.h"
#include "riscos/options.h"
@ -100,7 +103,7 @@ void ro_gui_interactive_help_request(wimp_message *message)
os_error *error;
const char *auto_text;
int i;
/* check we aren't turned off */
if (!option_interactive_help)
return;
@ -124,18 +127,17 @@ void ro_gui_interactive_help_request(wimp_message *message)
sprintf(message_token, "%s%i", auto_text, (int)icon);
else if (window == wimp_ICON_BAR)
sprintf(message_token, "HelpIconbar");
else if ((hotlist_tree) && (window == (wimp_w)hotlist_tree->handle)) {
i = ro_gui_tree_help(message_data->pos.x, message_data->pos.y);
else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) {
i = ro_treeview_get_help(message_data);
sprintf(message_token,
(i >= 0) ? "HelpTree%i" :"HelpHotlist%i", i);
} else if ((global_history_tree) &&
(window == (wimp_w)global_history_tree->handle)) {
i = ro_gui_tree_help(message_data->pos.x, message_data->pos.y);
} else if (ro_gui_global_history_check_window(
message->data.data_xfer.w)) {
i = ro_treeview_get_help(message_data);
sprintf(message_token,
(i >= 0) ? "HelpTree%i" :"HelpGHistory%i", i);
} else if ((cookies_tree) &&
(window == (wimp_w)cookies_tree->handle)) {
i = ro_gui_tree_help(message_data->pos.x, message_data->pos.y);
} else if (ro_gui_cookies_check_window(message->data.data_xfer.w)) {
i = ro_treeview_get_help(message_data);
sprintf(message_token,
(i >= 0) ? "HelpTree%i" :"HelpCookies%i", i);
} else if (ro_gui_window_lookup(window) != NULL)
@ -173,11 +175,11 @@ void ro_gui_interactive_help_request(wimp_message *message)
sprintf(message_token, "HelpIconMenu");
else if (current_menu == browser_menu)
sprintf(message_token, "HelpBrowserMenu");
else if (current_menu == hotlist_menu)
else if (ro_gui_hotlist_check_menu(current_menu))
sprintf(message_token, "HelpHotlistMenu");
else if (current_menu == global_history_menu)
else if (ro_gui_global_history_check_menu(current_menu))
sprintf(message_token, "HelpGHistoryMenu");
else if (current_menu == cookies_menu)
else if (ro_gui_cookies_check_menu(current_menu))
sprintf(message_token, "HelpCookiesMenu");
else
return;
@ -323,7 +325,7 @@ void ro_gui_interactive_help_start(void)
char *help_start;
wimp_t task = 0;
os_error *error;
/* don't launch a second copy of anything */
if (ro_gui_interactive_help_available())
return;

View File

@ -1,5 +1,6 @@
/*
* Copyright 2004, 2005 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -31,10 +32,13 @@
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/hotlist.h"
#include "desktop/tree.h"
#include "riscos/dialog.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/theme.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
@ -44,350 +48,300 @@
#include "utils/utils.h"
#include "utils/url.h"
static void ro_gui_hotlist_menu_prepare(wimp_w window, wimp_menu *menu);
static bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
static void ro_gui_hotlist_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action);
static void ro_gui_hotlist_visited(hlcache_handle *c, struct tree *tree,
struct node *node);
static bool ro_gui_hotlist_click(wimp_pointer *pointer);
/* The RISC OS hotlist window, toolbar and treeview data. */
static struct ro_hotlist {
wimp_w window; /*< The hotlist RO window handle. */
struct toolbar *toolbar; /*< The hotlist toolbar handle. */
ro_treeview *tv; /*< The hotlist treeview handle. */
wimp_menu *menu; /*< The hotlist window menu. */
} hotlist_window;
/* The hotlist window, toolbar and plot origins
*/
static wimp_w hotlist_window;
struct tree *hotlist_tree;
/**
* Pre-Initialise the hotlist tree. This is called for things that need to
* be done at the gui_init() stage, such as loading templates.
*/
/* Whether the editing facilities are for add so that we know how
to reset the dialog boxes on a adjust-cancel and the action to
perform on ok.
*/
struct node *dialog_folder_node;
struct node *dialog_entry_node;
static const struct {
const char *url;
const char *msg_key;
} default_entries[] = {
{ "http://www.netsurf-browser.org/", "HotlistHomepage" },
{ "http://www.netsurf-browser.org/downloads/riscos/testbuilds", "HotlistTestBuild" },
{ "http://www.netsurf-browser.org/documentation", "HotlistDocumentation" },
{ "http://sourceforge.net/tracker/?atid=464312&group_id=51719",
"HotlistBugTracker" },
{ "http://sourceforge.net/tracker/?atid=464315&group_id=51719",
"HotlistFeatureRequest" }
};
#define ENTRIES_COUNT (sizeof(default_entries) / sizeof(default_entries[0]))
void ro_gui_hotlist_initialise(void)
void ro_gui_hotlist_preinitialise(void)
{
FILE *fp;
struct node *node;
const struct url_data *data;
/* Create our window. */
/* create our window */
hotlist_window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(hotlist_window,
hotlist_window.window = ro_gui_dialog_create("tree");
ro_gui_set_window_title(hotlist_window.window,
messages_get("Hotlist"));
ro_gui_wimp_event_register_redraw_window(hotlist_window,
ro_gui_tree_redraw);
ro_gui_wimp_event_register_open_window(hotlist_window,
ro_gui_tree_open);
ro_gui_wimp_event_register_mouse_click(hotlist_window,
ro_gui_hotlist_click);
}
/* Either load or create a hotlist
*/
fp = fopen(option_hotlist_path, "r");
if (!fp) {
int i;
/**
* Initialise the hotlist tree, at the gui_init2() stage.
*/
hotlist_tree = calloc(sizeof(struct tree), 1);
if (!hotlist_tree) {
warn_user("NoMemory", 0);
return;
}
hotlist_tree->root = tree_create_folder_node(NULL, "Root");
if (!hotlist_tree->root) {
warn_user("NoMemory", 0);
free(hotlist_tree);
hotlist_tree = NULL;
return;
}
hotlist_tree->root->expanded = true;
node = tree_create_folder_node(hotlist_tree->root, "NetSurf");
if (!node)
node = hotlist_tree->root;
void ro_gui_hotlist_postinitialise(void)
{
/* Create our toolbar. */
for (i = 0; i != ENTRIES_COUNT; i++) {
data = urldb_get_url_data(default_entries[i].url);
if (!data) {
urldb_add_url(default_entries[i].url);
urldb_set_url_persistence(
default_entries[i].url,
true);
data = urldb_get_url_data(
default_entries[i].url);
}
if (data) {
tree_create_URL_node(node,
default_entries[i].url, data,
messages_get(default_entries[i].msg_key));
}
}
tree_initialise(hotlist_tree);
} else {
fclose(fp);
hotlist_tree = options_load_tree(option_hotlist_path);
}
if (!hotlist_tree) return;
hotlist_tree->handle = (int)hotlist_window;
hotlist_tree->movable = true;
ro_gui_wimp_event_set_user_data(hotlist_window, hotlist_tree);
ro_gui_wimp_event_register_keypress(hotlist_window,
ro_gui_tree_keypress);
/* Create our toolbar
*/
hotlist_tree->toolbar = ro_gui_theme_create_toolbar(NULL,
hotlist_window.toolbar = ro_gui_theme_create_toolbar(NULL,
THEME_HOTLIST_TOOLBAR);
if (hotlist_tree->toolbar)
ro_gui_theme_attach_toolbar(hotlist_tree->toolbar,
hotlist_window);
}
if (hotlist_window.toolbar)
ro_gui_theme_attach_toolbar(hotlist_window.toolbar,
hotlist_window.window);
/* Create the treeview with the window and toolbar. */
/**
* Perform a save to the default file
*/
void ro_gui_hotlist_save(void)
{
os_error *error;
if (!hotlist_tree)
hotlist_window.tv = ro_treeview_create(hotlist_window.window,
hotlist_window.toolbar, hotlist_get_tree_flags());
if (hotlist_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
/* Save to our file
*/
options_save_tree(hotlist_tree, option_hotlist_save,
"NetSurf hotlist");
error = xosfile_set_type(option_hotlist_save, 0xfaf);
if (error)
LOG(("xosfile_set_type: 0x%x: %s",
error->errnum, error->errmess));
}
/* Initialise the hotlist into the tree. */
hotlist_initialise(ro_treeview_get_tree(hotlist_window.tv),
option_hotlist_path);
/**
* Respond to a mouse click
*
* \param pointer the pointer state
*/
bool ro_gui_hotlist_click(wimp_pointer *pointer)
{
ro_gui_tree_click(pointer, hotlist_tree);
if (pointer->buttons == wimp_CLICK_MENU)
ro_gui_menu_create(hotlist_menu, pointer->pos.x,
pointer->pos.y, pointer->w);
else
ro_gui_menu_prepare_action(pointer->w, TREE_SELECTION, false);
return true;
}
/* Build the hotlist window menu. */
/**
* Informs the hotlist that some content has been visited
*
* \param content the content visited
*/
void hotlist_visited(hlcache_handle *c)
{
if ((!c) || (!content_get_url(c)) || (!hotlist_tree))
return;
ro_gui_hotlist_visited(c, hotlist_tree, hotlist_tree->root);
}
/**
* Informs the hotlist that some content has been visited
*
* \param content the content visited
* \param tree the tree to find the URL data from
* \param node the node to update siblings and children of
*/
void ro_gui_hotlist_visited(hlcache_handle *c, struct tree *tree,
struct node *node)
{
struct node_element *element;
for (; node; node = node->next) {
if (!node->folder) {
element = tree_find_element(node, TREE_ELEMENT_URL);
if ((element) && (!strcmp(element->text,
content_get_url(c)))) {
tree_update_URL_node(node, content_get_url(c),
NULL);
tree_handle_node_changed(tree, node, true,
false);
}
static const struct ns_menu hotlist_definition = {
"Hotlist", {
{ "Hotlist", NO_ACTION, 0 },
{ "Hotlist.New", NO_ACTION, 0 },
{ "Hotlist.New.Folder", TREE_NEW_FOLDER, 0 },
{ "Hotlist.New.Link", TREE_NEW_LINK, 0 },
{ "_Hotlist.Export", HOTLIST_EXPORT, &dialog_saveas },
{ "Hotlist.Expand", TREE_EXPAND_ALL, 0 },
{ "Hotlist.Expand.All", TREE_EXPAND_ALL, 0 },
{ "Hotlist.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "Hotlist.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "Hotlist.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "Hotlist.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "Hotlist.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "Hotlist.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "Hotlist.Toolbars", NO_ACTION, 0 },
{ "_Hotlist.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "Hotlist.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
{ "Selection.Edit", TREE_SELECTION_EDIT, 0 },
{ "Selection.Launch", TREE_SELECTION_LAUNCH, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
if (node->child)
ro_gui_hotlist_visited(c, tree, node->child);
}
};
hotlist_window.menu = ro_gui_menu_define_menu(&hotlist_definition);
ro_gui_wimp_event_register_window_menu(hotlist_window.window,
hotlist_window.menu, ro_gui_hotlist_menu_prepare,
ro_gui_hotlist_menu_select, NULL,
ro_gui_hotlist_menu_warning, false);
}
/**
* Prepares the folder dialog contents for a node
* Open the hotlist window.
*
* \param node the node to prepare the dialogue for, or NULL
*/
void ro_gui_hotlist_prepare_folder_dialog(struct node *node)
{
const char *name;
const char *title;
dialog_folder_node = node;
if (node) {
title = messages_get("EditFolder");
name = node->data.text;
} else {
title = messages_get("NewFolder");
name = messages_get("Folder");
void ro_gui_hotlist_open(void)
{
tree_set_redraw(ro_treeview_get_tree(hotlist_window.tv), true);
if (!ro_gui_dialog_open_top(hotlist_window.window,
hotlist_window.toolbar, 600, 800)) {
xwimp_set_caret_position(hotlist_window.window, -1, -100, -100, 32, -1);
// \todo ro_gui_theme_process_toolbar(hotlist_window.toolbar, -1);
ro_treeview_set_origin(hotlist_window.tv, 0,
-(ro_gui_theme_toolbar_height(
hotlist_window.toolbar)));
// ro_gui_tree_stop_edit(tree);
//
// if (tree->root->child) {
// tree_set_node_selected(tree, tree->root, false);
// tree_handle_node_changed(tree, tree->root,
// false, true);
// }
}
ro_gui_set_window_title(dialog_folder, title);
ro_gui_set_icon_string(dialog_folder, ICON_FOLDER_NAME, name, true);
ro_gui_wimp_event_memorise(dialog_folder);
}
/**
* Prepares the entry dialog contents for a node
* Prepare the hotlist menu for opening
*
* \param node the node to prepare the dialogue for, or NULL
* \param window The window owning the menu.
* \param *menu The menu about to be opened.
*/
void ro_gui_hotlist_prepare_entry_dialog(struct node *node)
{
struct node_element *element;
const char *name;
const char *title;
const char *url = "";
dialog_entry_node = node;
if (node) {
title = messages_get("EditLink");
name = node->data.text;
if ((element = tree_find_element(node, TREE_ELEMENT_URL)))
url = element->text;
} else {
title = messages_get("NewLink");
name = messages_get("Link");
}
ro_gui_set_window_title(dialog_entry, title);
ro_gui_set_icon_string(dialog_entry, ICON_ENTRY_NAME, name, true);
ro_gui_set_icon_string(dialog_entry, ICON_ENTRY_URL, url, true);
ro_gui_wimp_event_memorise(dialog_entry);
void ro_gui_hotlist_menu_prepare(wimp_w window, wimp_menu *menu)
{
bool selection;
selection = ro_treeview_has_selection(hotlist_window.tv);
ro_gui_menu_set_entry_shaded(hotlist_window.menu, TREE_SELECTION,
!selection);
ro_gui_menu_set_entry_shaded(hotlist_window.menu, TREE_CLEAR_SELECTION,
!selection);
ro_gui_menu_set_entry_shaded(hotlist_window.menu, TOOLBAR_BUTTONS,
(hotlist_window.toolbar == NULL ||
hotlist_window.toolbar->editor));
ro_gui_menu_set_entry_ticked(hotlist_window.menu, TOOLBAR_BUTTONS,
(hotlist_window.toolbar != NULL &&
(hotlist_window.toolbar->display_buttons ||
hotlist_window.toolbar->editor)));
ro_gui_menu_set_entry_shaded(hotlist_window.menu, TOOLBAR_EDIT,
hotlist_window.toolbar == NULL);
ro_gui_menu_set_entry_ticked(hotlist_window.menu, TOOLBAR_EDIT,
(hotlist_window.toolbar != NULL &&
hotlist_window.toolbar->editor));
ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML,
NULL, NULL, NULL, NULL);
}
/**
* Handle submenu warnings for the hotlist menu
*
* \param window The window owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
void ro_gui_hotlist_menu_warning(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
/* Do nothing */
}
/**
* Apply the settings of dialog window (folder/entry edit)
* Handle selections from the hotlist menu
*
* \param w the window to apply
* \param window The window owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
bool ro_gui_hotlist_dialog_apply(wimp_w w)
bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
struct node_element *element;
struct node *node;
const char *icon;
char *title;
char *url = NULL;
url_func_result res;
const struct url_data *data;
/* get our data */
if (w == dialog_entry) {
icon = ro_gui_get_icon_string(w, ICON_ENTRY_URL);
res = url_normalize(icon, &url);
if (res != URL_FUNC_OK) {
warn_user(res == URL_FUNC_FAILED ? "NoURLError"
: "NoMemory", 0);
return false;
}
icon = ro_gui_get_icon_string(w, ICON_ENTRY_NAME);
while (isspace(*icon))
icon++;
title = strdup(icon);
node = dialog_entry_node;
} else {
icon = ro_gui_get_icon_string(w, ICON_FOLDER_NAME);
while (isspace(*icon))
icon++;
title = strdup(icon);
node = dialog_folder_node;
}
if (title != NULL)
strip(title);
/* check for lack of text */
if (title == NULL || title[0] == '\0') {
if (title == NULL)
warn_user("NoMemory", 0);
else if (title[0] == '\0')
warn_user("NoNameError", 0);
free(url);
free(title);
node = NULL;
switch (action) {
case HOTLIST_EXPORT:
ro_gui_dialog_open_persistent(window, dialog_saveas, true);
return true;
case TREE_NEW_FOLDER:
hotlist_add_folder();
return true;
case TREE_NEW_LINK:
hotlist_add_entry();
return true;
case TREE_EXPAND_ALL:
hotlist_expand_all();
return true;
case TREE_EXPAND_FOLDERS:
hotlist_expand_directories();
return true;
case TREE_EXPAND_LINKS:
hotlist_expand_addresses();
return true;
case TREE_COLLAPSE_ALL:
hotlist_collapse_all();
return true;
case TREE_COLLAPSE_FOLDERS:
hotlist_collapse_directories();
return true;
case TREE_COLLAPSE_LINKS:
hotlist_collapse_addresses();
return true;
case TREE_SELECTION_EDIT:
hotlist_edit_selected();
return true;
case TREE_SELECTION_LAUNCH:
hotlist_launch_selected();
return true;
case TREE_SELECTION_DELETE:
hotlist_delete_selected();
return true;
case TREE_SELECT_ALL:
hotlist_select_all();
return true;
case TREE_CLEAR_SELECTION:
hotlist_clear_selection();
return true;
default:
return false;
}
ro_gui_set_icon_string(w, url ? ICON_ENTRY_NAME : ICON_FOLDER_NAME,
title, false);
/* update/insert our data */
if (!node) {
if (url) {
data = urldb_get_url_data(url);
if (!data) {
urldb_add_url(url);
urldb_set_url_persistence(url, true);
data = urldb_get_url_data(url);
}
if (!data) {
free(url);
free(title);
return false;
}
if (!data->title)
urldb_set_url_title(url, title);
node = dialog_entry_node = tree_create_URL_node(
hotlist_tree->root, url, data, title);
} else {
node = dialog_folder_node = tree_create_folder_node(
hotlist_tree->root, title);
}
free(url);
free(title);
if (!node) {
warn_user("NoMemory", 0);
return false;
}
tree_handle_node_changed(hotlist_tree, node, true, false);
ro_gui_tree_scroll_visible(hotlist_tree, &node->data);
tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP,
0, NODE_INSTEP, 16384);
} else {
element = tree_find_element(node, TREE_ELEMENT_URL);
if (element) {
free((void *)element->text);
element->text = url;
ro_gui_set_icon_string(w, ICON_ENTRY_URL, url, true);
}
free((void *)node->data.text);
node->data.text = title;
tree_handle_node_changed(hotlist_tree, node, true, false);
}
return true;
return false;
}
/**
* Update the theme details of the hotlist window.
*/
void ro_gui_hotlist_update_theme(void)
{
ro_treeview_update_theme(hotlist_window.tv);
}
/**
* Check if a particular window handle is the hotlist window
*
* \param window The window in question
* \return true if this window is the hotlist
*/
bool ro_gui_hotlist_check_window(wimp_w window)
{
if (hotlist_window.window == window)
return true;
else
return false;
}
/**
* Check if a particular menu handle is the hotlist menu
*
* \param *menu The menu in question.
* \return true if this menu is the hotlist menu
*/
bool ro_gui_hotlist_check_menu(wimp_menu *menu)
{
if (hotlist_window.menu == menu)
return true;
else
return false;
}
#if 0
/**
* Handle URL dropped on hotlist
*
* \param message the wimp message we're acting on
* \param url the URL to add
*/
void ro_gui_hotlist_url_drop(wimp_message *message, const char *url)
{
int x, y;
if (hotlist_window.window != message->data.data_xfer.w)
return;
ro_gui_tree_get_tree_coordinates(hotlist_window.tree,
message->data.data_xfer.pos.x,
message->data.data_xfer.pos.y,
&x, &y);
hotlist_add_page_xy(url, x, y);
}
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright 2008 François Revol <mmu_man@users.sourceforge.net>
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -17,20 +17,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NSBEOS_HISTORY_H__
#define __NSBEOS_HISTORY_H__
/** \file
* Hotlist (interface).
*/
#include <View.h>
#include <Window.h>
#ifndef _NETSURF_RISCOS_HOTLIST_H_
#define _NETSURF_RISCOS_HOTLIST_H_
extern BWindow *wndHistory;
void ro_gui_hotlist_preinitialise(void);
void ro_gui_hotlist_postinitialise(void);
void ro_gui_hotlist_open(void);
void ro_gui_hotlist_save(void);
void ro_gui_hotlist_update_theme(void);
bool ro_gui_hotlist_check_window(wimp_w window);
bool ro_gui_hotlist_check_menu(wimp_menu *menu);
void nsbeos_history_init(void);
void nsbeos_history_update(void);
#warning XXX
#if 0 /* GTK */
void nsbeos_history_row_activated(GtkTreeView *, GtkTreePath *,
GtkTreeViewColumn *, gpointer);
#endif
#endif /* __NSGTK_HISTORY_H__ */

View File

@ -34,9 +34,12 @@
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/cookies.h"
#include "desktop/browser.h"
#include "desktop/gui.h"
#include "desktop/history_global_core.h"
#include "desktop/history_core.h"
#include "desktop/hotlist.h"
#include "desktop/netsurf.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
@ -49,12 +52,14 @@
#include "riscos/gui.h"
#include "riscos/global_history.h"
#include "riscos/help.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/tinct.h"
#include "riscos/theme.h"
#include "riscos/treeview.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "utils/log.h"
@ -63,18 +68,6 @@
#include "utils/utils.h"
#include "utils/utf8.h"
struct ns_menu_entry {
const char *text; /**< menu text (from messages) */
menu_action action; /**< associated action */
wimp_w *sub_window; /**< sub-window if any */
};
struct ns_menu {
const char *title;
struct ns_menu_entry entries[];
};
struct menu_definition_entry {
menu_action action; /**< menu action */
wimp_menu_entry *menu_entry; /**< corresponding menu entry */
@ -91,7 +84,6 @@ struct menu_definition {
};
static wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu);
static void ro_gui_menu_define_menu_add(struct menu_definition *definition,
const struct ns_menu *menu, int depth,
wimp_menu_entry *parent_entry,
@ -101,15 +93,11 @@ static struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu,
menu_action action);
static menu_action ro_gui_menu_find_action(wimp_menu *menu,
wimp_menu_entry *menu_entry);
static void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action,
bool shaded);
static void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action,
bool ticked);
static void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g,
struct browser_window **bw, hlcache_handle **h,
struct toolbar **toolbar, struct tree **tree);
struct toolbar **toolbar,
bool *is_cookies, bool *is_hotlist, bool *is_global_history);
static int ro_gui_menu_get_checksum(void);
static bool ro_gui_menu_prepare_url_suggest(void);
static void ro_gui_menu_prepare_pageinfo(struct gui_window *g);
static void ro_gui_menu_prepare_objectinfo(hlcache_handle *object,
const char *href);
@ -143,12 +131,12 @@ static wimp_i current_menu_icon;
/** The height of the iconbar menu */
int iconbar_menu_height = 5 * 44;
/** The available menus */
wimp_menu *iconbar_menu, *browser_menu, *hotlist_menu, *global_history_menu, *cookies_menu,
*image_quality_menu, *browser_toolbar_menu,
*tree_toolbar_menu, *proxy_type_menu, *languages_menu;
/** URL suggestion menu */
static wimp_MENU(GLOBAL_HISTORY_RECENT_URLS) url_suggest;
wimp_menu *url_suggest_menu = (wimp_menu *)&url_suggest;
wimp_menu *iconbar_menu, *browser_menu, *image_quality_menu,
*browser_toolbar_menu, *tree_toolbar_menu,
*proxy_type_menu, *languages_menu;
static wimp_MENU(URL_SUGGEST_MAX_URLS) url_suggest_menu_block;
wimp_menu *url_suggest_menu = (wimp_menu *) &url_suggest_menu_block;
/* the values given in PRM 3-157 for how to check menus/windows are
* incorrect so we use a hack of checking if the sub-menu has bit 0
@ -277,94 +265,6 @@ void ro_gui_menu_init(void)
};
browser_menu = ro_gui_menu_define_menu(&browser_definition);
/* hotlist menu */
static wimp_w one = (wimp_w) 1;
static const struct ns_menu hotlist_definition = {
"Hotlist", {
{ "Hotlist", NO_ACTION, 0 },
{ "Hotlist.New", NO_ACTION, 0 },
{ "Hotlist.New.Folder", TREE_NEW_FOLDER, &dialog_folder },
{ "Hotlist.New.Link", TREE_NEW_LINK, &dialog_entry },
{ "_Hotlist.Export", HOTLIST_EXPORT, &dialog_saveas },
{ "Hotlist.Expand", TREE_EXPAND_ALL, 0 },
{ "Hotlist.Expand.All", TREE_EXPAND_ALL, 0 },
{ "Hotlist.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "Hotlist.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "Hotlist.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "Hotlist.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "Hotlist.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "Hotlist.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "Hotlist.Toolbars", NO_ACTION, 0 },
{ "_Hotlist.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "Hotlist.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
/* We want a window, but it changes depending upon
* context. Therefore, ensure that the structure is
* created so that we can dynamically modify the
* actual item presented. We do this by creating a
* fake wimp_w with the value 1, which indicates a
* window handle as opposed to a submenu. */
{ "Selection.Edit", TREE_SELECTION_EDIT, &one },
{ "Selection.Launch", TREE_SELECTION_LAUNCH, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
};
hotlist_menu = ro_gui_menu_define_menu(&hotlist_definition);
/* history menu */
static const struct ns_menu global_history_definition = {
"History", {
{ "History", NO_ACTION, 0 },
{ "_History.Export", HISTORY_EXPORT, &dialog_saveas },
{ "History.Expand", TREE_EXPAND_ALL, 0 },
{ "History.Expand.All", TREE_EXPAND_ALL, 0 },
{ "History.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "History.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "History.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "History.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "History.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "History.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "History.Toolbars", NO_ACTION, 0 },
{ "_History.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "History.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
{ "Selection.Launch", TREE_SELECTION_LAUNCH, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
};
global_history_menu = ro_gui_menu_define_menu(
&global_history_definition);
/* history menu */
static const struct ns_menu cookies_definition = {
"Cookies", {
{ "Cookies", NO_ACTION, 0 },
{ "Cookies.Expand", TREE_EXPAND_ALL, 0 },
{ "Cookies.Expand.All", TREE_EXPAND_ALL, 0 },
{ "Cookies.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
{ "Cookies.Expand.Links", TREE_EXPAND_LINKS, 0 },
{ "Cookies.Collapse", TREE_COLLAPSE_ALL, 0 },
{ "Cookies.Collapse.All", TREE_COLLAPSE_ALL, 0 },
{ "Cookies.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
{ "Cookies.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
{ "Cookies.Toolbars", NO_ACTION, 0 },
{ "_Cookies.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
{ "Cookies.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 },
{ "Selection", TREE_SELECTION, 0 },
{ "Selection.Delete", TREE_SELECTION_DELETE, 0 },
{ "SelectAll", TREE_SELECT_ALL, 0 },
{ "Clear", TREE_CLEAR_SELECTION, 0 },
{NULL, 0, 0}
}
};
cookies_menu = ro_gui_menu_define_menu(&cookies_definition);
/* image quality menu */
static const struct ns_menu images_definition = {
"Display", {
@ -415,9 +315,7 @@ void ro_gui_menu_init(void)
proxy_type_menu = ro_gui_menu_define_menu(&proxy_type_definition);
/* special case menus */
url_suggest_menu->title_data.indirected_text.text =
(char *) messages_get("URLSuggest");
ro_gui_menu_init_structure(url_suggest_menu, GLOBAL_HISTORY_RECENT_URLS);
ro_gui_url_suggest_init(url_suggest_menu);
/* Note: This table *must* be kept in sync with the LangNames file */
static const struct ns_menu lang_definition = {
@ -540,7 +438,7 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
/* prepare the menu state */
if (menu == url_suggest_menu) {
if (!ro_gui_menu_prepare_url_suggest())
if (!ro_gui_url_suggest_prepare_menu())
return;
} else if (menu == recent_search_menu) {
if (!ro_gui_search_prepare_menu())
@ -618,8 +516,8 @@ void ro_gui_menu_closed(bool cleanup)
struct browser_window *bw;
hlcache_handle *h;
struct toolbar *t;
struct tree *tree;
os_error *error;
bool is_cookies, is_hotlist, is_global_history;
if (current_menu) {
@ -630,15 +528,16 @@ void ro_gui_menu_closed(bool cleanup)
warn_user("MenuError", error->errmess);
}
ro_gui_menu_get_window_details(current_menu_window,
&g, &bw, &h, &t, &tree);
current_menu = NULL;
&g, &bw, &h, &t,
&is_cookies, &is_hotlist,
&is_global_history);
if (cleanup) {
ro_gui_wimp_event_menus_closed();
if (tree)
ro_gui_tree_menu_closed(tree);
ro_gui_wimp_event_menus_closed(current_menu_window,
current_menu_icon, current_menu);
}
current_menu = NULL;
}
current_menu_window = NULL;
@ -668,15 +567,16 @@ void ro_gui_menu_objects_moved(void)
*/
void ro_gui_menu_selection(wimp_selection *selection)
{
int i, j;
wimp_menu_entry *menu_entry;
menu_action action;
wimp_pointer pointer;
struct gui_window *g = NULL;
wimp_menu *menu;
os_error *error;
int previous_menu_icon = current_menu_icon;
char *url;
int i, j;
bool needs_prepare;
wimp_menu_entry *menu_entry;
menu_action action;
wimp_pointer pointer;
struct gui_window *g = NULL;
wimp_menu *menu;
os_error *error;
int previous_menu_icon = current_menu_icon;
char *url;
/* if we are using gui_multitask then menu selection events
* may be delivered after the menu has been closed. As such,
@ -686,42 +586,59 @@ void ro_gui_menu_selection(wimp_selection *selection)
assert(current_menu_window);
/* get the menu entry and associated action */
/* get the menu entry and associated action and definition */
menu_entry = &current_menu->entries[selection->items[0]];
for (i = 1; selection->items[i] != -1; i++)
menu_entry = &menu_entry->sub_menu->
entries[selection->items[i]];
action = ro_gui_menu_find_action(current_menu, menu_entry);
/* perform menu action */
if (action != NO_ACTION)
ro_gui_menu_handle_action(current_menu_window, action, false);
/* Deal with the menu action. We first pass it to Wimp_Event to
* handle any automatic menus. If this doesn't recognise the details,
* it is passed on to the code in menus.c.
*/
/* perform non-automated actions */
if (current_menu == url_suggest_menu) {
g = ro_gui_toolbar_lookup(current_menu_window);
if (g) {
url = url_suggest_menu->entries[selection->items[0]].
data.indirected_text.text;
gui_window_set_url(g, url);
browser_window_go(g->bw, url, 0, true);
global_history_add_recent(url);
}
} else if (current_menu == gui_form_select_menu) {
g = ro_gui_window_lookup(current_menu_window);
assert(g);
needs_prepare = false;
if (selection->items[0] >= 0) {
form_select_process_selection(g->bw->current_content,
gui_form_select_control,
selection->items[0]);
if (!ro_gui_wimp_event_menu_selection(current_menu_window,
current_menu_icon, current_menu, selection, action)) {
/* perform menu action */
if (action != NO_ACTION)
ro_gui_menu_handle_action(current_menu_window,
action, false);
/* perform non-automated actions */
if (current_menu == url_suggest_menu) {
g = ro_gui_toolbar_lookup(current_menu_window);
if (g) {
url = url_suggest_menu->entries[selection->items[0]].
data.indirected_text.text;
gui_window_set_url(g, url);
browser_window_go(g->bw, url, 0, true);
}
} else if (current_menu == gui_form_select_menu) {
g = ro_gui_window_lookup(current_menu_window);
assert(g);
if (selection->items[0] >= 0) {
form_select_process_selection(g->bw->current_content,
gui_form_select_control,
selection->items[0]);
}
}
/* allow automatic menus to have their data updated */
// ro_gui_wimp_event_menu_selection(current_menu_window,
// current_menu_icon, current_menu, selection);
/* Menus not handled by ro_gui_wimp_event_menu_selection()
* will need to be re-prepared before an adjust reopening.
*/
needs_prepare = true;
}
/* allow automatic menus to have their data updated */
ro_gui_wimp_event_menu_selection(current_menu_window, current_menu_icon,
current_menu, selection);
/* re-open the menu for Adjust clicks */
error = xwimp_get_pointer_info(&pointer);
if (error) {
@ -738,24 +655,26 @@ void ro_gui_menu_selection(wimp_selection *selection)
}
/* re-prepare all the visible entries */
i = 0;
menu = current_menu;
do {
j = 0;
if (needs_prepare) {
i = 0;
menu = current_menu;
do {
action = ro_gui_menu_find_action(current_menu,
&menu->entries[j]);
if (action != NO_ACTION)
ro_gui_menu_prepare_action(current_menu_window,
action, false);
} while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST));
j = selection->items[i++];
if (j != -1) {
menu = menu->entries[j].sub_menu;
if ((!menu) || (menu == wimp_NO_SUB_MENU))
break;
}
} while (j != -1);
j = 0;
do {
action = ro_gui_menu_find_action(current_menu,
&menu->entries[j]);
if (action != NO_ACTION)
ro_gui_menu_prepare_action(current_menu_window,
action, false);
} while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST));
j = selection->items[i++];
if (j != -1) {
menu = menu->entries[j].sub_menu;
if ((!menu) || (menu == wimp_NO_SUB_MENU))
break;
}
} while (j != -1);
}
if (current_menu == gui_form_select_menu) {
assert(g); /* Keep scan-build happy */
@ -788,28 +707,42 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
for (i = 1; warning->selection.items[i] != -1; i++)
menu_entry = &menu_entry->sub_menu->
entries[warning->selection.items[i]];
action = ro_gui_menu_find_action(current_menu, menu_entry);
if (IS_MENU(menu_entry->sub_menu)) {
ro_gui_wimp_event_register_submenu((wimp_w)0);
sub_menu = menu_entry->sub_menu;
i = 0;
do {
action = ro_gui_menu_find_action(current_menu,
&sub_menu->entries[i]);
/* We only process the menu in the old way if the wimp_event module
* hasn't processed it for us.
*/
if (!ro_gui_wimp_event_submenu_warning(current_menu_window,
current_menu_icon, current_menu, &(warning->selection),
action)) {
if (IS_MENU(menu_entry->sub_menu)) {
ro_gui_wimp_event_register_submenu((wimp_w)0);
sub_menu = menu_entry->sub_menu;
i = 0;
do {
action = ro_gui_menu_find_action(current_menu,
&sub_menu->entries[i]);
if (action != NO_ACTION)
ro_gui_menu_prepare_action(current_menu_window,
action, false);
} while (!(sub_menu->entries[i++].menu_flags &
wimp_MENU_LAST));
} else {
ro_gui_wimp_event_register_submenu((wimp_w)menu_entry->sub_menu);
action = ro_gui_menu_find_action(current_menu, menu_entry);
if (action != NO_ACTION)
ro_gui_menu_prepare_action(current_menu_window,
action, false);
} while (!(sub_menu->entries[i++].menu_flags & wimp_MENU_LAST));
} else {
ro_gui_wimp_event_register_submenu((wimp_w)menu_entry->sub_menu);
action = ro_gui_menu_find_action(current_menu, menu_entry);
if (action != NO_ACTION)
ro_gui_menu_prepare_action(current_menu_window,
action, true);
/* remove the close icon */
action, true);
}
}
/* If this is a dialogue box, remove the close and back icons. */
if (!(IS_MENU(menu_entry->sub_menu)))
ro_gui_wimp_update_window_furniture((wimp_w)menu_entry->sub_menu,
wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON, 0);
}
/* open the sub-menu */
error = xwimp_create_sub_menu(menu_entry->sub_menu,
@ -829,55 +762,37 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
*/
void ro_gui_menu_refresh_toolbar(struct toolbar *toolbar)
{
// struct treeview_window *treeview_window;
assert(toolbar);
toolbar->reformat_buttons = true;
ro_gui_theme_process_toolbar(toolbar, -1);
if (toolbar->type == THEME_BROWSER_TOOLBAR) {
gui_window_update_extent(ro_gui_window_lookup(current_menu_window));
} else if (toolbar->type == THEME_HOTLIST_TOOLBAR) {
tree_resized(hotlist_tree);
xwimp_force_redraw((wimp_w)hotlist_tree->handle,
0,-16384, 16384, 16384);
} else if (toolbar->type == THEME_HISTORY_TOOLBAR) {
tree_resized(global_history_tree);
xwimp_force_redraw((wimp_w)global_history_tree->handle,
0,-16384, 16384, 16384);
} else if (toolbar->type == THEME_COOKIES_TOOLBAR) {
tree_resized(cookies_tree);
xwimp_force_redraw((wimp_w)cookies_tree->handle,
0,-16384, 16384, 16384);
gui_window_update_extent(ro_gui_window_lookup(
current_menu_window));
// } else if (toolbar->type == THEME_HOTLIST_TOOLBAR) {
// treeview_window = ro_gui_hotlist_get();
// /* TODO: FIX THIS */
// /* tree_resized(treeview_window->tree); */
// xwimp_force_redraw(treeview_window->window,
// 0,-16384, 16384, 16384);
// } else if (toolbar->type == THEME_HISTORY_TOOLBAR) {
// treeview_window = ro_gui_global_history_get();
// /* TODO: FIX THIS */
// /* tree_resized(treeview_window->tree); */
// xwimp_force_redraw(treeview_window->window,
// 0,-16384, 16384, 16384);
// } else if (toolbar->type == THEME_COOKIES_TOOLBAR) {
// treeview_window = ro_gui_cookies_get();
// /* TODO: FIX THIS */
// /* tree_resized(treeview_window->tree); */
// xwimp_force_redraw(treeview_window->window,
// 0,-16384, 16384, 16384);
}
}
/**
* Builds the URL suggestion menu
*/
bool ro_gui_menu_prepare_url_suggest(void) {
char **suggest_text;
int suggestions;
int i;
suggest_text = global_history_get_recent(&suggestions);
if (suggestions < 1)
return false;
for (i = 0; i < suggestions; i++) {
url_suggest_menu->entries[i].menu_flags = 0;
url_suggest_menu->entries[i].data.indirected_text.text =
suggest_text[i];
url_suggest_menu->entries[i].data.indirected_text.size =
strlen(suggest_text[i]) + 1;
}
url_suggest_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED;
url_suggest_menu->entries[suggestions - 1].menu_flags |= wimp_MENU_LAST;
return true;
}
/**
* Update navigate menu status and toolbar icons.
*
@ -885,8 +800,6 @@ bool ro_gui_menu_prepare_url_suggest(void) {
*/
void ro_gui_prepare_navigate(struct gui_window *gui)
{
int suggestions;
ro_gui_menu_prepare_action(gui->window, HOTLIST_SHOW, false);
ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_STOP, false);
ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_RELOAD_ALL,
@ -902,9 +815,9 @@ void ro_gui_prepare_navigate(struct gui_window *gui)
ro_gui_menu_prepare_action(gui->window, BROWSER_FIND_TEXT, false);
if (gui->toolbar) {
global_history_get_recent(&suggestions);
ro_gui_set_icon_shaded_state(gui->toolbar->toolbar_handle,
ICON_TOOLBAR_SUGGEST, (suggestions <= 0));
ICON_TOOLBAR_SUGGEST,
!ro_gui_url_suggest_prepare_menu());
}
}
@ -1122,8 +1035,10 @@ void gui_create_form_select_menu(struct browser_window *bw,
/**
* Creates a wimp_menu and adds it to the list to handle actions for.
*
* \param menu the data to create the menu with
* \return the menu created, or NULL on failure
* \param *menu The data to create the menu with
* \param *callbacks A callback table for the menu (NULL if to be
* handled in the 'old-fashined way' by menus.c).
* \return The menu created, or NULL on failure
*/
wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu)
{
@ -1475,13 +1390,12 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
struct browser_window *bw = NULL;
hlcache_handle *h = NULL;
struct toolbar *t = NULL;
struct tree *tree;
struct node *node;
os_error *error;
char url[80];
const struct url_data *data;
bool is_cookies, is_hotlist, is_global_history;
ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t, &tree);
ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t,
&is_cookies, &is_hotlist, &is_global_history);
switch (action) {
@ -1515,42 +1429,26 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
windows_at_pointer);
return true;
case HISTORY_SHOW_GLOBAL:
ro_gui_tree_show(global_history_tree);
ro_gui_global_history_open();
return true;
/* hotlist actions */
case HOTLIST_ADD_URL:
if ((!hotlist_tree) || (!h) || (!content_get_url(h)))
if (h == NULL || content_get_url(h) == NULL)
return false;
data = urldb_get_url_data(content_get_url(h));
if (data) {
node = tree_create_URL_node(hotlist_tree->root,
content_get_url(h),
data, data->title);
if (node) {
tree_redraw_area(hotlist_tree,
node->box.x - NODE_INSTEP, 0,
NODE_INSTEP, 16384);
tree_handle_node_changed(hotlist_tree,
node, false, true);
ro_gui_tree_scroll_visible(hotlist_tree,
&node->data);
ro_gui_hotlist_save();
}
}
hotlist_add_page(content_get_url(h));
return true;
case HOTLIST_SHOW:
ro_gui_tree_show(hotlist_tree);
ro_gui_hotlist_open();
return true;
/* cookies actions */
case COOKIES_SHOW:
ro_gui_tree_show(cookies_tree);
ro_gui_cookies_open();
return true;
case COOKIES_DELETE:
if (cookies_tree->root->child)
tree_delete_node(cookies_tree, cookies_tree->root->child, true);
cookies_delete_all();
return true;
/* page actions */
@ -1635,8 +1533,6 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
if (!h)
return false;
/* Fall through */
case HOTLIST_EXPORT:
case HISTORY_EXPORT:
ro_gui_menu_prepare_action(owner, action, true);
ro_gui_dialog_open_persistent(owner, dialog_saveas,
windows_at_pointer);
@ -1788,61 +1684,6 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
ro_gui_save_options();
return true;
/* tree actions */
case TREE_NEW_FOLDER:
ro_gui_menu_prepare_action(owner, action, true);
ro_gui_dialog_open_persistent((wimp_w)tree->handle,
dialog_folder, windows_at_pointer);
return true;
case TREE_NEW_LINK:
ro_gui_menu_prepare_action(owner, action, true);
ro_gui_dialog_open_persistent((wimp_w)tree->handle,
dialog_entry, windows_at_pointer);
return true;
case TREE_EXPAND_ALL:
case TREE_EXPAND_FOLDERS:
case TREE_EXPAND_LINKS:
tree_handle_expansion(tree, tree->root, true,
(action != TREE_EXPAND_LINKS),
(action != TREE_EXPAND_FOLDERS));
return true;
case TREE_COLLAPSE_ALL:
case TREE_COLLAPSE_FOLDERS:
case TREE_COLLAPSE_LINKS:
tree_handle_expansion(tree, tree->root, false,
(action != TREE_COLLAPSE_LINKS),
(action != TREE_COLLAPSE_FOLDERS));
return true;
case TREE_SELECTION_EDIT:
return true;
case TREE_SELECTION_LAUNCH:
ro_gui_tree_launch_selected(tree);
return true;
case TREE_SELECTION_DELETE:
ro_gui_tree_stop_edit(tree);
tree_delete_selected_nodes(tree, tree->root);
if (tree == hotlist_tree)
ro_gui_hotlist_save();
ro_gui_menu_prepare_action(owner, TREE_CLEAR_SELECTION, true);
ro_gui_menu_prepare_action(owner, TREE_SELECTION, true);
return true;
case TREE_SELECT_ALL:
ro_gui_tree_stop_edit(tree);
if (tree->root->child) {
tree->temp_selection = NULL;
tree_set_node_selected(tree, tree->root, true);
}
ro_gui_menu_prepare_action(owner, TREE_CLEAR_SELECTION, true);
ro_gui_menu_prepare_action(owner, TREE_SELECTION, true);
return true;
case TREE_CLEAR_SELECTION:
tree->temp_selection = NULL;
ro_gui_tree_stop_edit(tree);
tree_set_node_selected(tree, tree->root, false);
ro_gui_menu_prepare_action(owner, TREE_CLEAR_SELECTION, true);
ro_gui_menu_prepare_action(owner, TREE_SELECTION, true);
return true;
/* toolbar actions */
case TOOLBAR_BUTTONS:
assert(t);
@ -1895,21 +1736,20 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
bool windows)
{
struct menu_definition_entry *entry;
struct gui_window *g;
struct browser_window *bw;
hlcache_handle *h;
struct toolbar *t;
struct tree *tree;
struct node *node;
bool result = false;
int checksum = 0;
os_error *error;
char *parent;
url_func_result res;
bool compare;
bool is_cookies, is_hotlist, is_global_history;
ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t, &tree);
ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t,
&is_cookies, &is_hotlist, &is_global_history);
if (current_menu_open)
checksum = ro_gui_menu_get_checksum();
if (!h) {
@ -1935,35 +1775,11 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
!(h || history_back_available(bw->history) ||
history_forward_available(bw->history))));
break;
case HISTORY_SHOW_GLOBAL:
ro_gui_menu_set_entry_shaded(current_menu, action,
!global_history_tree);
break;
/* hotlist actions */
case HOTLIST_ADD_URL:
ro_gui_menu_set_entry_shaded(current_menu, action,
(!h || !hotlist_tree));
break;
case HOTLIST_SHOW:
ro_gui_menu_set_entry_shaded(current_menu, action,
!hotlist_tree);
if ((t) && (!t->editor) &&
(t->type == THEME_BROWSER_TOOLBAR))
ro_gui_set_icon_shaded_state(
t->toolbar_handle,
ICON_TOOLBAR_BOOKMARK,
!hotlist_tree);
break;
/* cookies actions */
case COOKIES_SHOW:
ro_gui_menu_set_entry_shaded(current_menu, action,
!cookies_tree);
break;
case COOKIES_DELETE:
ro_gui_menu_set_entry_shaded(current_menu, action,
!(cookies_tree && cookies_tree->root->child));
h == NULL);
break;
/* page actions */
@ -2003,7 +1819,8 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
/* object actions */
case BROWSER_OBJECT:
ro_gui_menu_set_entry_shaded(current_menu, action,
!current_menu_object && !current_menu_url);
!current_menu_object &&
!current_menu_url);
break;
case BROWSER_OBJECT_LINK:
@ -2013,7 +1830,8 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
case BROWSER_OBJECT_INFO:
if (windows && current_menu_object)
ro_gui_menu_prepare_objectinfo(current_menu_object,
ro_gui_menu_prepare_objectinfo(
current_menu_object,
current_menu_url);
/* Fall through */
case BROWSER_OBJECT_RELOAD:
@ -2024,7 +1842,8 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
case BROWSER_OBJECT_PRINT:
/* not yet implemented */
ro_gui_menu_set_entry_shaded(current_menu, action, true);
ro_gui_menu_set_entry_shaded(current_menu, action,
true);
break;
/* save actions (browser, hotlist, history) */
@ -2032,7 +1851,8 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
ro_gui_menu_set_entry_shaded(current_menu,
action, !current_menu_object);
if (windows && current_menu_object)
ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG, current_menu_object,
ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
current_menu_object,
NULL, NULL, NULL);
break;
case BROWSER_OBJECT_EXPORT:
@ -2047,41 +1867,41 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
if (h) {
switch (content_get_type(h)) {
/* \todo - this classification should prob be done in content_() */
/* bitmap types (Sprite export possible) */
/* bitmap types (Sprite export possible) */
#ifdef WITH_JPEG
case CONTENT_JPEG:
case CONTENT_JPEG:
#endif
#ifdef WITH_MNG
case CONTENT_JNG:
case CONTENT_MNG:
case CONTENT_JNG:
case CONTENT_MNG:
#endif
#ifdef WITH_GIF
case CONTENT_GIF:
case CONTENT_GIF:
#endif
#ifdef WITH_BMP
case CONTENT_BMP:
case CONTENT_ICO:
case CONTENT_BMP:
case CONTENT_ICO:
#endif
#if defined(WITH_MNG) || defined(WITH_PNG)
case CONTENT_PNG:
case CONTENT_PNG:
#endif
#ifdef WITH_SPRITE
case CONTENT_SPRITE:
case CONTENT_SPRITE:
#endif
exp_sprite = true;
break;
exp_sprite = true;
break;
/* vector types (Draw export possible) */
/* vector types (Draw export possible) */
#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
case CONTENT_SVG:
case CONTENT_SVG:
#endif
#ifdef WITH_DRAW
case CONTENT_DRAW:
case CONTENT_DRAW:
#endif
exp_draw = true;
break;
exp_draw = true;
break;
default: break;
default: break;
}
}
@ -2229,16 +2049,6 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
content_get_url(h),
content_get_title(h));
break;
case HOTLIST_EXPORT:
if ((tree) && (windows))
ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML,
NULL, NULL, NULL, NULL);
break;
case HISTORY_EXPORT:
if ((tree) && (windows))
ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML,
NULL, NULL, NULL, NULL);
break;
/* navigation actions */
case BROWSER_NAVIGATE_BACK:
@ -2379,82 +2189,7 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
break;
/* tree actions */
case TREE_NEW_FOLDER:
ro_gui_hotlist_prepare_folder_dialog(NULL);
break;
case TREE_NEW_LINK:
ro_gui_hotlist_prepare_entry_dialog(NULL);
break;
case TREE_EXPAND_ALL:
case TREE_EXPAND_FOLDERS:
case TREE_EXPAND_LINKS:
case TREE_COLLAPSE_ALL:
case TREE_COLLAPSE_FOLDERS:
case TREE_COLLAPSE_LINKS:
if ((tree) && (tree->root)) {
ro_gui_menu_set_entry_shaded(current_menu,
action, !tree->root->child);
if ((t) && (!t->editor) && (t->type !=
THEME_BROWSER_TOOLBAR)) {
ro_gui_set_icon_shaded_state(
t->toolbar_handle,
ICON_TOOLBAR_EXPAND,
!tree->root->child);
ro_gui_set_icon_shaded_state(
t->toolbar_handle,
ICON_TOOLBAR_OPEN,
!tree->root->child);
}
}
break;
case TREE_SELECTION:
if ((!tree) || (!tree->root))
break;
if (tree->root->child)
result = tree_has_selection(tree->root->child);
ro_gui_menu_set_entry_shaded(current_menu,
action, !result);
if ((t) && (!t->editor) &&
(t->type != THEME_BROWSER_TOOLBAR)) {
ro_gui_set_icon_shaded_state(
t->toolbar_handle,
ICON_TOOLBAR_DELETE, !result);
ro_gui_set_icon_shaded_state(
t->toolbar_handle,
ICON_TOOLBAR_LAUNCH, !result);
}
break;
case TREE_SELECTION_EDIT:
node = tree_get_selected_node(tree->root);
entry = ro_gui_menu_find_entry(current_menu, action);
if ((!node) || (!entry))
break;
if (node->folder) {
entry->menu_entry->sub_menu =
(wimp_menu *)dialog_folder;
if (windows)
ro_gui_hotlist_prepare_folder_dialog(node);
} else {
entry->menu_entry->sub_menu =
(wimp_menu *)dialog_entry;
if (windows)
ro_gui_hotlist_prepare_entry_dialog(node);
}
break;
case TREE_SELECTION_LAUNCH:
case TREE_SELECTION_DELETE:
case TREE_CLEAR_SELECTION:
if ((!tree) || (!tree->root))
break;
if (tree->root->child)
result = tree_has_selection(tree->root->child);
ro_gui_menu_set_entry_shaded(current_menu,
action, !result);
break;
case TREE_SELECT_ALL:
ro_gui_menu_set_entry_shaded(current_menu, action,
!tree->root->child);
break;
/* toolbar actions */
@ -2509,31 +2244,35 @@ void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
*/
void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g,
struct browser_window **bw, hlcache_handle **h,
struct toolbar **toolbar, struct tree **tree)
struct toolbar **toolbar,
bool *is_cookies, bool *is_hotlist, bool *is_global_history)
{
*is_cookies = false;
*is_hotlist = false;
*is_global_history = false;
*g = ro_gui_window_lookup(w);
if (*g) {
*bw = (*g)->bw;
*toolbar = (*g)->toolbar;
if (*bw)
*h = (*bw)->current_content;
*tree = NULL;
} else {
*bw = NULL;
*h = NULL;
if ((hotlist_tree) && (w == (wimp_w)hotlist_tree->handle))
*tree = hotlist_tree;
else if ((global_history_tree) &&
(w == (wimp_w)global_history_tree->handle))
*tree = global_history_tree;
else if ((cookies_tree) && (w == (wimp_w)cookies_tree->handle))
*tree = cookies_tree;
else
*tree = NULL;
if (*tree)
*toolbar = (*tree)->toolbar;
else
if (ro_gui_hotlist_check_window(w)) {
*is_hotlist = true;
// *toolbar = treeview_window->toolbar;
} else if (ro_gui_global_history_check_window(w)) {
*is_global_history = true;
// *toolbar = treeview_window->toolbar;
} else if (ro_gui_cookies_check_window(w)) {
*is_cookies = true;
// *toolbar = treeview_window->toolbar;
} else {
*toolbar = NULL;
}
}
}
@ -2595,6 +2334,7 @@ bool ro_gui_menu_translate(struct menu_definition *menu)
char *translated;
utf8_convert_ret err;
/* read current alphabet */
error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet);
if (error) {

View File

@ -155,6 +155,20 @@ typedef enum {
} menu_action;
/* Menu entry structures for use when defining menus. */
struct ns_menu_entry {
const char *text; /**< menu text (from messages) */
menu_action action; /**< associated action */
wimp_w *sub_window; /**< sub-window if any */
};
struct ns_menu {
const char *title;
struct ns_menu_entry entries[];
};
void ro_gui_menu_init(void);
void ro_gui_menu_create(wimp_menu* menu, int x, int y, wimp_w w);
bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
@ -171,4 +185,10 @@ void ro_gui_prepare_navigate(struct gui_window *gui);
const char *ro_gui_menu_find_menu_entry_key(wimp_menu *menu,
const char *translated);
wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu);
void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action,
bool shaded);
void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action,
bool ticked);
#endif

View File

@ -37,6 +37,8 @@
#include "oslib/wimpspriteop.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "desktop/hotlist.h"
#include "desktop/history_global_core.h"
#include "desktop/netsurf.h"
#include "desktop/save_complete.h"
#include "desktop/save_text.h"
@ -630,9 +632,9 @@ void ro_gui_save_drag_end(wimp_dragged *drag)
while (!dest_ok && (box = box_at_point(box,
pos.x, pos.y, &box_x, &box_y,
&h))) {
if (box->style &&
if (box->style &&
css_computed_visibility(
box->style) ==
box->style) ==
CSS_VISIBILITY_HIDDEN)
continue;
@ -897,8 +899,7 @@ bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite)
LINK_TEXT, path);
case GUI_SAVE_HOTLIST_EXPORT_HTML:
if (!options_save_tree(hotlist_tree, path,
"NetSurf hotlist"))
if (!hotlist_export(path))
return false;
error = xosfile_set_type(path, 0xfaf);
if (error)
@ -906,8 +907,7 @@ bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite)
error->errnum, error->errmess));
break;
case GUI_SAVE_HISTORY_EXPORT_HTML:
if (!options_save_tree(global_history_tree, path,
"NetSurf history"))
if (!history_global_export(path))
return false;
error = xosfile_set_type(path, 0xfaf);
if (error)
@ -1346,7 +1346,7 @@ void ro_gui_save_set_state(hlcache_handle *h, gui_save_type save_type,
}
/* leafname */
if (url && url_nice(url, &nice, option_strip_extensions) ==
if (url && url_nice(url, &nice, option_strip_extensions) ==
URL_FUNC_OK) {
for (i = 0; nice[i]; i++) {
if (nice[i] == '.')

View File

@ -1,5 +1,6 @@
/*
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -32,9 +33,11 @@
#include "content/fetch.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/sslcert.h"
#include "desktop/gui.h"
#include "desktop/tree.h"
#include "riscos/dialog.h"
#include "riscos/sslcert.h"
#include "riscos/textarea.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
@ -47,50 +50,36 @@
#define ICON_SSL_REJECT 3
#define ICON_SSL_ACCEPT 4
#define ICON_CERT_VERSION 3
#define ICON_CERT_VALID_FROM 5
#define ICON_CERT_TYPE 7
#define ICON_CERT_VALID_TO 9
#define ICON_CERT_SERIAL 11
#define ICON_CERT_ISSUER 13
#define ICON_CERT_SUBJECT 15
static wimp_window *ro_gui_cert_dialog_template;
static wimp_window *ro_gui_cert_tree_template;
static wimp_window *dialog_tree_template;
static wimp_window *dialog_cert_template;
static wimp_window *dialog_display_template;
struct session_data {
struct session_cert *certs;
unsigned long num;
char *url;
struct tree *tree;
nserror (*cb)(bool proceed, void *pw);
void *cbpw;
};
struct session_cert {
char version[16], valid_from[32], valid_to[32], type[8], serial[32];
char *issuer_t;
char *subject_t;
uintptr_t issuer;
uintptr_t subject;
struct ro_sslcert
{
wimp_w window;
wimp_w pane;
ro_treeview *tv;
struct sslcert_session_data *data;
};
static bool ro_gui_cert_click(wimp_pointer *pointer);
static void ro_gui_cert_close(wimp_w w);
static bool ro_gui_cert_apply(wimp_w w);
static void ro_gui_cert_accept(wimp_pointer *pointer);
static void ro_gui_cert_reject(wimp_pointer *pointer);
static void ro_gui_cert_close_window(wimp_w w);
static void ro_gui_cert_release_window(struct ro_sslcert *s);
/**
* Load the cert window template
* Load and initialise the certificate window template
*/
void ro_gui_cert_init(void)
void ro_gui_cert_preinitialise(void)
{
dialog_tree_template = ro_gui_dialog_load_template("tree");
dialog_cert_template = ro_gui_dialog_load_template("sslcert");
dialog_display_template = ro_gui_dialog_load_template("ssldisplay");
/* Load templates for the SSL windows and adjust the tree window
* flags to suit.
*/
dialog_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE |
ro_gui_cert_dialog_template = ro_gui_dialog_load_template("sslcert");
ro_gui_cert_tree_template = ro_gui_dialog_load_template("tree");
ro_gui_cert_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE |
wimp_WINDOW_BACK_ICON |
wimp_WINDOW_CLOSE_ICON |
wimp_WINDOW_TITLE_ICON |
@ -98,170 +87,170 @@ void ro_gui_cert_init(void)
wimp_WINDOW_TOGGLE_ICON);
}
/**
* Load and initialise the certificate window template
*/
void ro_gui_cert_postinitialise(void)
{
/* Initialise the SSL module. */
sslcert_init();
}
/**
* Open the certificate verification dialog
*
* \param *bw The browser window owning the certificates.
* \param *c The content data corresponding to the
* certificates.
* \param *certs The certificate details.
* \param num The number of certificates included.
*/
void gui_cert_verify(const char *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
wimp_w w;
wimp_w ssl_w;
const struct ssl_cert_info *from;
struct session_cert *to;
struct session_data *data;
struct tree *tree;
struct node *node;
wimp_window_state state;
wimp_icon_state istate;
os_error *error;
long i;
struct ro_sslcert *sslcert_window;
wimp_window_state state;
wimp_icon_state istate;
wimp_window_info info;
os_error *error;
bool set_extent;
assert(certs);
/* copy the certificate information */
data = calloc(1, sizeof(struct session_data));
if (!data) {
warn_user("NoMemory", 0);
sslcert_window = malloc(sizeof(struct ro_sslcert));
if (sslcert_window == NULL) {
LOG(("Failed to allocate memory for SSL Cert Dialog"));
return;
}
data->url = strdup(url);
if (!data->url) {
free(data);
warn_user("NoMemory", 0);
return;
}
data->cb = cb;
data->cbpw = cbpw;
data->num = num;
data->certs = calloc(num, sizeof(struct session_cert));
if (!data->certs) {
free(data->url);
free(data);
warn_user("NoMemory", 0);
return;
}
for (i = 0; i < (long)num; i++) {
to = &data->certs[i];
from = &certs[i];
to->subject_t = strdup(from->subject);
to->issuer_t = strdup(from->issuer);
if ((!to->subject_t) || (!to->issuer_t)) {
for (; i >= 0; i--) {
to = &data->certs[i];
free(to->subject_t);
free(to->issuer_t);
}
free(data->certs);
free(data->url);
free(data);
warn_user("NoMemory", 0);
return;
}
snprintf(to->version, sizeof data->certs->version, "%ld",
from->version);
snprintf(to->valid_from, sizeof data->certs->valid_from, "%s",
from->not_before);
snprintf(to->type, sizeof data->certs->type, "%d",
from->cert_type);
snprintf(to->valid_to, sizeof data->certs->valid_to, "%s",
from->not_after);
snprintf(to->serial, sizeof data->certs->serial, "%ld",
from->serial);
}
/* create the SSL window */
error = xwimp_create_window(dialog_cert_template, &ssl_w);
/* Create the SSL window and its pane. */
error = xwimp_create_window(ro_gui_cert_dialog_template,
&(sslcert_window->window));
if (error) {
free(data->certs);
free(data->url);
free(data);
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
free(sslcert_window);
return;
}
error = xwimp_create_window(ro_gui_cert_tree_template,
&(sslcert_window->pane));
if (error) {
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
free(sslcert_window);
return;
}
/* Create the SSL data and build a tree from it. */
sslcert_window->tv = ro_treeview_create(sslcert_window->pane, NULL,
sslcert_get_tree_flags());
if (sslcert_window->tv == NULL) {
LOG(("Failed to allocate treeview"));
free(sslcert_window);
return;
}
sslcert_window->data = sslcert_create_session_data(num, url, cb, cbpw);
sslcert_load_tree(ro_treeview_get_tree(sslcert_window->tv),
certs, sslcert_window->data);
tree_set_redraw(ro_treeview_get_tree(sslcert_window->tv), true);
/* Set up the certificate window event handling.
*
* (The action buttons are registered as button events, not OK and
* Cancel, as both need to carry out actions.)
*/
ro_gui_wimp_event_set_user_data(sslcert_window->window, sslcert_window);
ro_gui_wimp_event_register_close_window(sslcert_window->window,
ro_gui_cert_close_window);
ro_gui_wimp_event_register_button(sslcert_window->window,
ICON_SSL_REJECT, ro_gui_cert_reject);
ro_gui_wimp_event_register_button(sslcert_window->window,
ICON_SSL_ACCEPT, ro_gui_cert_accept);
ro_gui_dialog_open_persistent(NULL, sslcert_window->window, false);
/* Nest the tree window inside the pane window. To do this, we:
* - Get the current pane extent,
* - Get the parent window position and the location of the pane-
* locating icon inside it,
* - Set the visible area of the pane to suit,
* - Check that the pane extents are OK for this visible area, and
* increase them if necessary,
* - Before finally opening the pane as a nested part of the parent.
*/
info.w = sslcert_window->pane;
error = xwimp_get_window_info_header_only(&info);
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_get_window_info: 0x%x: %s",
error->errnum, error->errmess));
return;
}
/* automated SSL window event handling */
ro_gui_wimp_event_set_user_data(ssl_w, data);
ro_gui_wimp_event_register_cancel(ssl_w, ICON_SSL_REJECT);
ro_gui_wimp_event_register_ok(ssl_w, ICON_SSL_ACCEPT, ro_gui_cert_apply);
ro_gui_dialog_open_persistent(NULL, ssl_w, false);
/* create a tree window (styled as a list) */
error = xwimp_create_window(dialog_tree_template, &w);
if (error) {
ro_gui_cert_close(ssl_w);
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
return;
}
tree = calloc(sizeof(struct tree), 1);
if (!tree) {
ro_gui_cert_close(ssl_w);
warn_user("NoMemory", 0);
return;
}
tree->root = tree_create_folder_node(NULL, "Root");
if (!tree->root) {
ro_gui_cert_close(ssl_w);
warn_user("NoMemory", 0);
free(tree);
tree = NULL;
return;
}
tree->root->expanded = true;
tree->handle = (int)w;
tree->movable = false;
tree->no_drag = true;
tree->no_vscroll = true;
tree->no_furniture = true;
tree->single_selection = true;
data->tree = tree;
/* put the SSL names in the tree */
for (i = 0; i < (long)num; i++) {
node = tree_create_leaf_node(tree->root, certs[i].subject);
if (node) {
node->data.data = TREE_ELEMENT_SSL;
tree_set_node_sprite(node, "small_xxx", "small_xxx");
}
}
/* automated treeview event handling */
ro_gui_wimp_event_set_user_data(w, tree);
ro_gui_wimp_event_register_keypress(w, ro_gui_tree_keypress);
ro_gui_wimp_event_register_redraw_window(w, ro_gui_tree_redraw);
ro_gui_wimp_event_register_open_window(w, ro_gui_tree_open);
ro_gui_wimp_event_register_close_window(w, ro_gui_wimp_event_finalise);
ro_gui_wimp_event_register_mouse_click(w, ro_gui_cert_click);
/* nest the tree window inside the pane window */
state.w = ssl_w;
state.w = sslcert_window->window;
error = xwimp_get_window_state(&state);
if (error) {
ro_gui_cert_close(ssl_w);
ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_get_window_state: 0x%x: %s",
error->errnum, error->errmess));
return;
}
istate.w = ssl_w;
istate.w = sslcert_window->window;
istate.i = ICON_SSL_PANE;
error = xwimp_get_icon_state(&istate);
if (error) {
ro_gui_cert_close(ssl_w);
ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_get_icon_state: 0x%x: %s",
error->errnum, error->errmess));
return;
}
state.w = w;
state.w = sslcert_window->pane;
state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - 20 -
ro_get_vscroll_width(w);
ro_get_vscroll_width(sslcert_window->pane);
state.visible.x0 += istate.icon.extent.x0 + 20;
state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + 20;
state.visible.y1 += istate.icon.extent.y1 - 32;
error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), ssl_w,
set_extent = false;
if ((info.extent.x1 - info.extent.x0) <
(state.visible.x1 - state.visible.x0)) {
info.extent.x0 = 0;
info.extent.x1 = state.visible.x1 - state.visible.x0;
set_extent = true;
}
if ((info.extent.y1 - info.extent.y0) <
(state.visible.y1 - state.visible.y0)) {
info.extent.y1 = 0;
info.extent.x1 = state.visible.y0 - state.visible.y1;
set_extent = true;
}
if (set_extent) {
error = xwimp_set_extent(sslcert_window->pane, &(info.extent));
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_set_extent: 0x%x: %s",
error->errnum, error->errmess));
return;
}
}
error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state),
sslcert_window->window,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_XORIGIN_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
@ -271,192 +260,100 @@ void gui_cert_verify(const char *url,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_RS_EDGE_SHIFT);
if (error) {
ro_gui_cert_close(ssl_w);
ro_gui_cert_release_window(sslcert_window);
LOG(("xwimp_open_window_nested: 0x%x: %s",
error->errnum, error->errmess));
ro_gui_cert_release_window(sslcert_window);
return;
}
tree_initialise(tree);
}
void ro_gui_cert_open(struct tree *tree, struct node *node)
{
struct node *n;
struct session_data *data;
struct session_cert *session;
wimp_window_state state;
wimp_w child;
wimp_w parent;
wimp_w w;
unsigned long i;
os_error *error;
assert(tree->root);
/* firstly we need to get our node index in the list */
for (n = tree->root->child, i = 0; n; i++, n = n->next)
if (n == node)
break;
assert(n);
/* now we get the handle of our list window */
child = (wimp_w)tree->handle;
assert(child);
/* now we can get the linked parent handle */
state.w = child;
error = xwimp_get_window_state_and_nesting(&state, &parent, 0);
if (error) {
LOG(("xwimp_get_window_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
return;
}
assert(parent);
/* from this we can get our session data */
data = (struct session_data *)ro_gui_wimp_event_get_user_data(parent);
assert(data);
assert(data->tree == tree);
/* and finally the nodes session certificate data */
session = &data->certs[i];
assert(session);
dialog_display_template->icons[ICON_CERT_VERSION].data.indirected_text.text = session->version;
dialog_display_template->icons[ICON_CERT_VERSION].data.indirected_text.size = strlen(session->version) + 1;
dialog_display_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.text = session->valid_from;
dialog_display_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.size = strlen(session->valid_from) + 1;
dialog_display_template->icons[ICON_CERT_TYPE].data.indirected_text.text = session->type;
dialog_display_template->icons[ICON_CERT_TYPE].data.indirected_text.size = strlen(session->type) + 1;
dialog_display_template->icons[ICON_CERT_VALID_TO].data.indirected_text.text = session->valid_to;
dialog_display_template->icons[ICON_CERT_VALID_TO].data.indirected_text.size = strlen(session->valid_to) + 1;
dialog_display_template->icons[ICON_CERT_SERIAL].data.indirected_text.text = session->serial;
dialog_display_template->icons[ICON_CERT_SERIAL].data.indirected_text.size = strlen(session->serial) + 1;
error = xwimp_create_window(dialog_display_template, &w);
if (error) {
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
free(session);
warn_user("MiscError", error->errmess);
return;
}
if (session->issuer)
ro_textarea_destroy(session->issuer);
session->issuer = ro_textarea_create(w, ICON_CERT_ISSUER,
TEXTAREA_MULTILINE | TEXTAREA_READONLY,
ro_gui_desktop_font_family, ro_gui_desktop_font_size,
ro_gui_desktop_font_style);
if (!session->issuer) {
xwimp_delete_window(w);
warn_user("NoMemory", 0);
return;
}
if (!ro_textarea_set_text(session->issuer, session->issuer_t)) {
ro_textarea_destroy(session->issuer);
xwimp_delete_window(w);
warn_user("NoMemory", 0);
return;
}
if (session->subject)
ro_textarea_destroy(session->subject);
session->subject = ro_textarea_create(w, ICON_CERT_SUBJECT,
TEXTAREA_MULTILINE | TEXTAREA_READONLY,
ro_gui_desktop_font_family, ro_gui_desktop_font_size,
ro_gui_desktop_font_style);
if (!session->subject) {
ro_textarea_destroy(session->issuer);
xwimp_delete_window(w);
warn_user("NoMemory", 0);
return;
}
if (!ro_textarea_set_text(session->subject, session->subject_t)) {
ro_textarea_destroy(session->subject);
ro_textarea_destroy(session->issuer);
xwimp_delete_window(w);
warn_user("NoMemory", 0);
return;
}
ro_gui_wimp_event_register_close_window(w, ro_gui_wimp_event_finalise);
ro_gui_dialog_open_persistent(parent, w, false);
}
/**
* Handle closing of certificate verification dialog
* Handle acceptance of certificate via event callback.
*
* \param *pointer The wimp pointer block.
*/
void ro_gui_cert_close(wimp_w w)
void ro_gui_cert_accept(wimp_pointer *pointer)
{
struct ro_sslcert *s;
s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w);
if (s != NULL) {
sslcert_accept(s->data);
ro_gui_dialog_close(s->window);
ro_gui_cert_release_window(s);
}
}
/**
* Handle rejection of certificate via event callback.
*
* \param w The wimp pointer block.
*/
void ro_gui_cert_reject(wimp_pointer *pointer)
{
struct ro_sslcert *s;
s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w);
if (s != NULL) {
sslcert_reject(s->data);
ro_gui_dialog_close(s->window);
ro_gui_cert_release_window(s);
}
}
/**
* Callback to handle the closure of the SSL dialogue by other means.
*
* \param w The window being closed.
*/
static void ro_gui_cert_close_window(wimp_w w)
{
struct ro_sslcert *s;
s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(w);
if (s != NULL)
ro_gui_cert_release_window(s);
}
/**
* Handle closing of the RISC OS certificate verification dialog, deleting
* the windows and freeing up the treeview and data block.
*
* \param *s The data block associated with the dialogue.
*/
void ro_gui_cert_release_window(struct ro_sslcert *s)
{
struct session_data *data;
os_error *error;
unsigned long i;
data = (struct session_data *)ro_gui_wimp_event_get_user_data(w);
assert(data);
if (s == NULL)
return;
/* If we didn't accept the certificate, send failure response */
if (data->cb != NULL)
data->cb(false, data->cbpw);
LOG(("Releasing SSL data: 0x%x", (unsigned) s));
for (i = 0; i < data->num; i++) {
if (data->certs[i].subject)
ro_textarea_destroy(data->certs[i].subject);
if (data->certs[i].issuer)
ro_textarea_destroy(data->certs[i].issuer);
}
free(data->certs);
free(data->url);
if (data->tree) {
tree_delete_node(data->tree, data->tree->root, false);
ro_gui_dialog_close((wimp_w)data->tree->handle);
error = xwimp_delete_window((wimp_w)data->tree->handle);
if (error) {
LOG(("xwimp_delete_window: 0x%x:%s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise((wimp_w)data->tree->handle);
free(data->tree);
}
free(data);
ro_gui_wimp_event_finalise(s->window);
ro_treeview_destroy(s->tv);
ro_gui_dialog_close(w);
error = xwimp_delete_window(w);
error = xwimp_delete_window(s->window);
if (error) {
LOG(("xwimp_delete_window: 0x%x:%s",
error->errnum, error->errmess));
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
error = xwimp_delete_window(s->pane);
if (error) {
LOG(("xwimp_delete_window: 0x%x:%s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
/**
* Handle acceptance of certificate
*/
bool ro_gui_cert_apply(wimp_w w)
{
struct session_data *session;
session = (struct session_data *)ro_gui_wimp_event_get_user_data(w);
assert(session);
urldb_set_cert_permissions(session->url, true);
session->cb(true, session->cbpw);
/* Flag that we sent response by invalidating callback details */
session->cb = NULL;
session->cbpw = NULL;
return true;
}
bool ro_gui_cert_click(wimp_pointer *pointer)
{
struct tree *tree;
tree = (struct tree *)ro_gui_wimp_event_get_user_data(pointer->w);
ro_gui_tree_click(pointer, tree);
return true;
free(s);
}

32
riscos/sslcert.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright 2006 Richard Wilson <info@tinct.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* 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
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* SSL certificate viewer (interface).
*/
#ifndef _NETSURF_RISCOS_SSLCERT_H_
#define _NETSURF_RISCOS_SSLCERT_H_
void ro_gui_cert_preinitialise(void);
void ro_gui_cert_postinitialise(void);
void ro_gui_cert_open(struct tree *tree, struct node *node);
#endif

View File

@ -183,7 +183,8 @@ void ro_gui_selection_drag_end(struct gui_window *g, wimp_dragged *drag)
if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
browser_window_mouse_drag_end(g->bw,
ro_gui_mouse_click_state(pointer.buttons),
ro_gui_mouse_click_state(pointer.buttons,
wimp_BUTTON_CLICK_DRAG),
pos.x, pos.y);
}
@ -542,8 +543,8 @@ void ro_gui_selection_dragging(wimp_message *message)
int box_x = 0;
int box_y = 0;
/* with autoscrolling, we will probably need to remember the
* gui_window and override the drag->w window handle which
/* with autoscrolling, we will probably need to remember the
* gui_window and override the drag->w window handle which
* could be any window on the desktop */
g = ro_gui_window_lookup(drag->w);
@ -566,14 +567,14 @@ void ro_gui_selection_dragging(wimp_message *message)
html_get_box_tree(h)) {
struct box *box = html_get_box_tree(h);
while ((box = box_at_point(box, pos.x, pos.y,
while ((box = box_at_point(box, pos.x, pos.y,
&box_x, &box_y, &h))) {
if (box->style &&
css_computed_visibility(box->style) ==
if (box->style &&
css_computed_visibility(box->style) ==
CSS_VISIBILITY_HIDDEN)
continue;
if (box->gadget &&
if (box->gadget &&
box->gadget->type == GADGET_TEXTAREA) {
textarea = box;
gadget_box_x = box_x;
@ -594,10 +595,10 @@ void ro_gui_selection_dragging(wimp_message *message)
gui_window_set_pointer(g, GUI_POINTER_CARET);
text_box = textarea_get_position(textarea, pos.x - gadget_box_x,
pos.y - gadget_box_y,
pos.y - gadget_box_y,
&char_offset, &pixel_offset);
caret_set_position(&ghost_caret, bw, text_box,
caret_set_position(&ghost_caret, bw, text_box,
char_offset, pixel_offset);
drag_claimed = true;
@ -613,16 +614,16 @@ void ro_gui_selection_dragging(wimp_message *message)
wimp_full_message_drag_claim claim;
os_error *error;
claim.size =
claim.size =
offsetof(wimp_full_message_drag_claim, file_types) + 8;
claim.your_ref = drag->my_ref;
claim.action = message_DRAG_CLAIM;
claim.flags = wimp_DRAG_CLAIM_POINTER_CHANGED |
claim.flags = wimp_DRAG_CLAIM_POINTER_CHANGED |
wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX;
claim.file_types[0] = osfile_TYPE_TEXT;
claim.file_types[1] = ~0;
error = xwimp_send_message(wimp_USER_MESSAGE,
error = xwimp_send_message(wimp_USER_MESSAGE,
(wimp_message *) &claim, drag->sender);
if (error) {
LOG(("xwimp_send_message: 0x%x: %s",

View File

@ -38,8 +38,11 @@
#include "oslib/wimpspriteop.h"
#include "content/content.h"
#include "desktop/gui.h"
#include "riscos/cookies.h"
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/theme.h"
@ -585,9 +588,9 @@ bool ro_gui_theme_apply(struct theme_descriptor *descriptor)
/* apply the theme to all the current windows */
ro_gui_window_update_theme();
ro_gui_tree_update_theme(hotlist_tree);
ro_gui_tree_update_theme(global_history_tree);
ro_gui_tree_update_theme(cookies_tree);
ro_gui_cookies_update_theme();
ro_gui_global_history_update_theme();
ro_gui_hotlist_update_theme();
ro_gui_theme_close(theme_previous, false);
return true;
}
@ -944,14 +947,16 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor,
ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle,
ro_gui_toolbar_click);
break;
case THEME_HOTLIST_TOOLBAR:
case THEME_HOTLIST_EDIT_TOOLBAR:
case THEME_HISTORY_TOOLBAR:
case THEME_HISTORY_EDIT_TOOLBAR:
case THEME_COOKIES_TOOLBAR:
case THEME_COOKIES_EDIT_TOOLBAR:
ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle,
ro_gui_tree_toolbar_click);
case THEME_HOTLIST_TOOLBAR:
case THEME_HOTLIST_EDIT_TOOLBAR:
case THEME_HISTORY_TOOLBAR:
case THEME_HISTORY_EDIT_TOOLBAR:
case THEME_COOKIES_TOOLBAR:
case THEME_COOKIES_EDIT_TOOLBAR:
ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle,
ro_gui_treeview_toolbar_click);
break;
default:
break;
}
@ -1322,6 +1327,7 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width)
xwimp_force_redraw(toolbar->parent_handle,
0, -16384, 16384, 16384);
}
}
/* Reformat the buttons starting with the throbber

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
* Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@ -24,38 +25,30 @@
#define _NETSURF_RISCOS_TREEVIEW_H_
#include <stdbool.h>
#include "oslib/osspriteop.h"
#include "oslib/wimp.h"
#include <oslib/help.h>
#include <oslib/wimp.h>
#include "desktop/tree.h"
#include "image/bitmap.h"
#define TREE_TEXT_HEIGHT 40
#define TREE_SPRITE_WIDTH 40 /* text plus sprite entries only */
typedef struct ro_treeview ro_treeview;
struct node_sprite {
osspriteop_area *area;
char name[12];
char expanded_name[12];
struct ro_treeview_table {
void (*open_menu)(wimp_pointer *pointer);
};
bool ro_gui_tree_initialise(void);
void ro_gui_tree_redraw(wimp_draw *redraw);
bool ro_gui_tree_click(wimp_pointer *pointer, struct tree *tree);
void ro_gui_tree_menu_closed(struct tree *tree);
bool ro_gui_tree_toolbar_click(wimp_pointer* pointer);
void ro_gui_tree_stop_edit(struct tree *tree);
void ro_gui_tree_open(wimp_open *open);
void ro_gui_tree_show(struct tree *tree);
bool ro_gui_tree_keypress(wimp_key *key);
void ro_gui_tree_selection_drag_end(wimp_dragged *drag);
void ro_gui_tree_move_drag_end(wimp_dragged *drag);
void ro_gui_tree_launch_selected(struct tree *tree);
void ro_gui_tree_start_edit(struct tree *tree, struct node_element *element,
wimp_pointer *pointer);
void ro_gui_tree_scroll_visible(struct tree *tree, struct node_element *element);
void ro_gui_tree_get_tree_coordinates(struct tree *tree, int x, int y,
int *tree_x, int *tree_y);
int ro_gui_tree_help(int x, int y);
void ro_gui_tree_update_theme(struct tree *tree);
ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar,
unsigned int flags);
void ro_treeview_destroy(ro_treeview *tv);
struct tree *ro_treeview_get_tree(ro_treeview *tv);
wimp_w ro_treeview_get_window(ro_treeview *tv);
bool ro_treeview_has_selection(ro_treeview *tv);
void ro_treeview_set_origin(ro_treeview *tv, int x, int y);
void ro_treeview_mouse_at(wimp_w w, wimp_pointer *pointer);
bool ro_gui_treeview_toolbar_click(wimp_pointer *pointer);
void ro_treeview_update_theme(ro_treeview *tv);
int ro_treeview_get_help(help_full_message_request *message_data);
#endif

Some files were not shown because too many files have changed in this diff Show More