mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
Merge treeview-redux to trunk
svn path=/trunk/netsurf/; revision=10865
This commit is contained in:
parent
195c1ea319
commit
6173bb0e6c
BIN
!NetSurf/Resources/Icons/content.png
Normal file
BIN
!NetSurf/Resources/Icons/content.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 685 B |
BIN
!NetSurf/Resources/Icons/directory.png
Normal file
BIN
!NetSurf/Resources/Icons/directory.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 259 B |
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
149
amiga/cookies.c
149
amiga/cookies.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
89
amiga/gui.c
89
amiga/gui.c
@ -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);
|
||||
|
12
amiga/gui.h
12
amiga/gui.h
@ -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);
|
||||
|
||||
|
357
amiga/history.c
357
amiga/history.c
@ -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++;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
138
amiga/hotlist.c
138
amiga/hotlist.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
478
amiga/menu.c
478
amiga/menu.c
@ -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
|
||||
|
15
amiga/menu.h
15
amiga/menu.h
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 }, \
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
1
amiga/resources/Themes/Default/content.png
Symbolic link
1
amiga/resources/Themes/Default/content.png
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../!NetSurf/Resources/Icons/content.png
|
1
amiga/resources/Themes/Default/directory.png
Symbolic link
1
amiga/resources/Themes/Default/directory.png
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../!NetSurf/Resources/Icons/directory.png
|
216
amiga/sslcert.c
216
amiga/sslcert.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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);
|
||||
|
1411
amiga/tree.c
1411
amiga/tree.c
File diff suppressed because it is too large
Load Diff
29
amiga/tree.h
29
amiga/tree.h
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
531
desktop/cookies.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
464
desktop/history_global_core.c
Normal file
464
desktop/history_global_core.c
Normal 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);
|
||||
}
|
44
desktop/history_global_core.h
Normal file
44
desktop/history_global_core.h
Normal 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
457
desktop/hotlist.c
Normal 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
54
desktop/hotlist.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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
276
desktop/sslcert.c
Normal 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
43
desktop/sslcert.h
Normal 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
|
3404
desktop/tree.c
3404
desktop/tree.c
File diff suppressed because it is too large
Load Diff
281
desktop/tree.h
281
desktop/tree.h
@ -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
846
desktop/tree_url_node.c
Normal 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
56
desktop/tree_url_node.h
Normal 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
|
@ -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
|
||||
*
|
||||
|
@ -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
213
gtk/gtk_cookies.c
Normal 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;
|
||||
}
|
@ -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__ */
|
149
gtk/gtk_gui.c
149
gtk/gtk_gui.c
@ -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)
|
||||
|
@ -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(¤t_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;
|
||||
}
|
||||
|
@ -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
277
gtk/gtk_hotlist.c
Normal 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;
|
||||
}
|
@ -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__ */
|
@ -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);
|
||||
|
@ -78,6 +78,7 @@ struct nsgtk_nav_menu {
|
||||
GtkImageMenuItem *globalhistory_menuitem;
|
||||
GtkImageMenuItem *addbookmarks_menuitem;
|
||||
GtkImageMenuItem *showbookmarks_menuitem;
|
||||
GtkImageMenuItem *showcookies_menuitem;
|
||||
GtkImageMenuItem *openlocation_menuitem;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -74,6 +74,7 @@ TOOLPROTO(localhistory);
|
||||
TOOLPROTO(globalhistory);
|
||||
TOOLPROTO(addbookmarks);
|
||||
TOOLPROTO(showbookmarks);
|
||||
TOOLPROTO(showcookies);
|
||||
TOOLPROTO(openlocation);
|
||||
TOOLPROTO(nexttab);
|
||||
TOOLPROTO(prevtab);
|
||||
|
@ -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
50
gtk/gtk_treeview.h
Normal 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__*/
|
@ -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);
|
||||
|
@ -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
174
gtk/res/cookies.glade
Normal 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>
|
@ -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"><b>_Search for</b></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
218
gtk/res/hotlist.glade
Normal 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
1
gtk/res/icons
Symbolic link
@ -0,0 +1 @@
|
||||
../../!NetSurf/Resources/Icons/
|
@ -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>
|
||||
|
@ -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,
|
||||
|
366
riscos/cookies.c
366
riscos/cookies.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
81
riscos/gui.c
81
riscos/gui.c
@ -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);
|
||||
}
|
||||
|
17
riscos/gui.h
17
riscos/gui.h
@ -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);
|
||||
|
@ -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;
|
||||
|
560
riscos/hotlist.c
560
riscos/hotlist.c
@ -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
|
||||
|
||||
|
@ -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__ */
|
678
riscos/menus.c
678
riscos/menus.c
@ -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 = ¤t_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) {
|
||||
|
@ -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
|
||||
|
@ -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] == '.')
|
||||
|
555
riscos/sslcert.c
555
riscos/sslcert.c
@ -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
32
riscos/sslcert.h
Normal 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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
2236
riscos/treeview.c
2236
riscos/treeview.c
File diff suppressed because it is too large
Load Diff
@ -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
Loading…
Reference in New Issue
Block a user