Merge branch 'master' of git://git.netsurf-browser.org/netsurf into tlsa/selection-search-refactor
This commit is contained in:
commit
8b6665fe03
11
Docs/env.sh
11
Docs/env.sh
|
@ -43,8 +43,10 @@ NS_GIT="git://git.netsurf-browser.org"
|
|||
NS_INTERNAL_LIBS="buildsystem libwapcaplet libparserutils libhubbub libdom libcss libnsgif libnsbmp libsvgtiny librosprite"
|
||||
# internal libraries only required by some frontends
|
||||
NS_FRONTEND_LIBS="libnsfb"
|
||||
# internal libraries required for the risc os target abi
|
||||
NS_RISCOS_LIBS="librufl libpencil"
|
||||
# tools required to build the browser
|
||||
NS_TOOLS="nsgenjsbind"
|
||||
NS_TOOLS="nsgenbind"
|
||||
# The browser itself
|
||||
NS_BROWSER="netsurf"
|
||||
|
||||
|
@ -53,6 +55,11 @@ NS_DEV_DEB="build-essential pkg-config git gperf"
|
|||
NS_TOOL_DEB="flex bison"
|
||||
NS_GTK_DEB="libgtk2.0-dev libcurl3-dev libmng-dev librsvg2-dev liblcms1-dev libjpeg-dev libmozjs-dev"
|
||||
|
||||
#add target specific libraries
|
||||
if [ "x${TARGET_ABI}" = "xriscos" ]; then
|
||||
NS_FRONTEND_LIBS="${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS}"
|
||||
fi
|
||||
|
||||
# apt get commandline to install necessary dev packages
|
||||
ns-apt-get-install()
|
||||
{
|
||||
|
@ -76,7 +83,7 @@ ns-pull()
|
|||
ns-clone()
|
||||
{
|
||||
mkdir -p ${TARGET_WORKSPACE}
|
||||
for REPO in $(echo ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do
|
||||
for REPO in $(echo ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do
|
||||
echo -n " GIT: Cloning ${REPO}: "
|
||||
if [ -f ${TARGET_WORKSPACE}/${REPO}/.git/config ]; then
|
||||
echo "Repository already present"
|
||||
|
|
|
@ -63,9 +63,9 @@ NETSURF_USE_VIDEO := NO
|
|||
|
||||
# Enable NetSurf's use of spidermonkey for javascript
|
||||
# Valid options: YES, NO, AUTO
|
||||
NETSURF_USE_JS := NO
|
||||
NETSURF_USE_JS := AUTO
|
||||
# Javascript support in older debian/ubuntu versions
|
||||
NETSURF_USE_MOZJS := NO
|
||||
NETSURF_USE_MOZJS := AUTO
|
||||
|
||||
# Enable NetSurf's use of libharu for PDF export and GTK printing support.
|
||||
# There is no auto-detection available for this, as it does not have a
|
||||
|
|
|
@ -92,6 +92,7 @@ nserror content__init(struct content *c, const content_handler *handler,
|
|||
if (fallback_charset != NULL) {
|
||||
c->fallback_charset = strdup(fallback_charset);
|
||||
if (c->fallback_charset == NULL) {
|
||||
free(user_sentinel);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
@ -1349,39 +1350,33 @@ struct content *content_clone(struct content *c)
|
|||
*/
|
||||
nserror content__clone(const struct content *c, struct content *nc)
|
||||
{
|
||||
struct content_user *user_sentinel;
|
||||
nserror error;
|
||||
|
||||
user_sentinel = calloc(1, sizeof(struct content_user));
|
||||
if (user_sentinel == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = llcache_handle_clone(c->llcache, &(nc->llcache));
|
||||
if (error != NSERROR_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
llcache_handle_change_callback(nc->llcache,
|
||||
content_llcache_callback, nc);
|
||||
|
||||
llcache_handle_change_callback(nc->llcache,
|
||||
content_llcache_callback, nc);
|
||||
|
||||
nc->mime_type = lwc_string_ref(c->mime_type);
|
||||
nc->handler = c->handler;
|
||||
|
||||
nc->status = c->status;
|
||||
|
||||
|
||||
nc->width = c->width;
|
||||
nc->height = c->height;
|
||||
nc->available_width = c->available_width;
|
||||
nc->quirks = c->quirks;
|
||||
|
||||
|
||||
if (c->fallback_charset != NULL) {
|
||||
nc->fallback_charset = strdup(c->fallback_charset);
|
||||
if (nc->fallback_charset == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (c->refresh != NULL) {
|
||||
nc->refresh = nsurl_ref(c->refresh);
|
||||
if (nc->refresh == NULL) {
|
||||
|
@ -1392,21 +1387,24 @@ nserror content__clone(const struct content *c, struct content *nc)
|
|||
nc->time = c->time;
|
||||
nc->reformat_time = c->reformat_time;
|
||||
nc->size = c->size;
|
||||
|
||||
|
||||
if (c->title != NULL) {
|
||||
nc->title = strdup(c->title);
|
||||
if (nc->title == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nc->active = c->active;
|
||||
|
||||
nc->user_list = user_sentinel;
|
||||
|
||||
nc->user_list = calloc(1, sizeof(struct content_user));
|
||||
if (nc->user_list == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
memcpy(&(nc->status_message), &(c->status_message), 120);
|
||||
memcpy(&(nc->sub_status), &(c->sub_status), 80);
|
||||
|
||||
|
||||
nc->locked = c->locked;
|
||||
nc->total_size = c->total_size;
|
||||
nc->http_code = c->http_code;
|
||||
|
|
|
@ -1185,6 +1185,7 @@ static nserror llcache_object_add_user(llcache_object *object,
|
|||
{
|
||||
assert(user->next == NULL);
|
||||
assert(user->prev == NULL);
|
||||
assert(user->handle != NULL);
|
||||
|
||||
user->handle->object = object;
|
||||
|
||||
|
|
|
@ -576,7 +576,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
|
|||
|
||||
/* counter-increment */
|
||||
val = css_computed_counter_increment(style, &counter);
|
||||
if (counter == NULL) {
|
||||
if ((val == CSS_COUNTER_INCREMENT_NONE) || (counter == NULL)) {
|
||||
fprintf(stream, "counter-increment: none ");
|
||||
} else {
|
||||
fprintf(stream, "counter-increment:");
|
||||
|
@ -596,7 +596,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
|
|||
|
||||
/* counter-reset */
|
||||
val = css_computed_counter_reset(style, &counter);
|
||||
if (counter == NULL) {
|
||||
if ((val == CSS_COUNTER_RESET_NONE) || (counter == NULL)) {
|
||||
fprintf(stream, "counter-reset: none ");
|
||||
} else {
|
||||
fprintf(stream, "counter-reset:");
|
||||
|
|
|
@ -2889,6 +2889,8 @@ void browser_window_redraw_rect(struct browser_window *bw, int x, int y,
|
|||
|
||||
void browser_window_page_drag_start(struct browser_window *bw, int x, int y)
|
||||
{
|
||||
assert(bw != NULL);
|
||||
|
||||
browser_window_set_drag_type(bw, DRAGGING_PAGE_SCROLL, NULL);
|
||||
|
||||
bw->drag_start_x = x;
|
||||
|
|
|
@ -264,19 +264,12 @@ 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,
|
||||
node = tree_create_leaf_node(cookies_tree,
|
||||
NULL,
|
||||
data->name,
|
||||
false, false, false);
|
||||
if (node == NULL) {
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -329,44 +322,33 @@ static void cookies_schedule_callback(const 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;
|
||||
}
|
||||
/* ownership of domain_cp passed to tree, if node creation
|
||||
* does not fail */
|
||||
node = tree_create_folder_node(cookies_tree,
|
||||
cookies_tree_root, domain_cp,
|
||||
cookies_tree_root,
|
||||
data->domain,
|
||||
false, false, false);
|
||||
if (node != NULL) {
|
||||
tree_set_node_user_callback(node, cookies_node_callback,
|
||||
tree_set_node_user_callback(node,
|
||||
cookies_node_callback,
|
||||
NULL);
|
||||
tree_set_node_icon(cookies_tree, node, folder_icon);
|
||||
|
||||
} else {
|
||||
free(domain_cp);
|
||||
}
|
||||
}
|
||||
|
||||
if (node == NULL)
|
||||
return;
|
||||
if (node != NULL) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -175,33 +175,24 @@ 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);
|
||||
title = messages_get(weekday_msg_name[full_time->tm_wday]);
|
||||
}
|
||||
|
||||
if (buffer == NULL) {
|
||||
LOG(("malloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
node = tree_create_folder_node(NULL, NULL, buffer,
|
||||
false, true, true);
|
||||
node = tree_create_folder_node(NULL, NULL, title, false, true, true);
|
||||
if (node == NULL) {
|
||||
LOG(("malloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
free(buffer);
|
||||
warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
|
||||
return false;
|
||||
}
|
||||
if (folder_icon != NULL)
|
||||
|
||||
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;
|
||||
|
|
|
@ -121,7 +121,6 @@ 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 */
|
||||
|
@ -143,18 +142,15 @@ bool hotlist_initialise(struct tree *tree, const char *hotlist_path,
|
|||
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);
|
||||
node = tree_create_folder_node(hotlist_tree,
|
||||
hotlist_tree_root,
|
||||
messages_get("NetSurf"),
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
if (node == NULL) {
|
||||
free(name);
|
||||
warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -373,14 +369,7 @@ void hotlist_collapse_addresses(void)
|
|||
void hotlist_add_folder(bool selected)
|
||||
{
|
||||
struct node *node, *parent = NULL;
|
||||
struct node_element *element;
|
||||
char *title = strdup("Untitled");
|
||||
|
||||
if (title == NULL) {
|
||||
LOG(("malloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
creating_node = true;
|
||||
|
||||
if (selected == true) {
|
||||
|
@ -394,16 +383,21 @@ void hotlist_add_folder(bool selected)
|
|||
parent = tree_get_default_folder_node(hotlist_tree);
|
||||
}
|
||||
|
||||
node = tree_create_folder_node(hotlist_tree, parent, title,
|
||||
true, false, false);
|
||||
node = tree_create_folder_node(hotlist_tree,
|
||||
parent,
|
||||
messages_get("Untitled"),
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
if (node == NULL) {
|
||||
free(title);
|
||||
warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
|
||||
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);
|
||||
tree_start_edit(hotlist_tree,
|
||||
tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -119,19 +119,22 @@ static node_callback_resp sslcert_node_callback(void *user_data,
|
|||
|
||||
static struct node *sslcert_create_node(const struct ssl_cert_info *cert)
|
||||
{
|
||||
struct node *node;
|
||||
struct node *node = NULL;
|
||||
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) {
|
||||
if (text != NULL) {
|
||||
node = tree_create_leaf_node(NULL,
|
||||
NULL,
|
||||
text,
|
||||
false, false, false);
|
||||
free(text);
|
||||
}
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tree_set_node_user_callback(node, sslcert_node_callback, NULL);
|
||||
|
||||
/* add issuer node */
|
||||
|
|
106
desktop/tree.c
106
desktop/tree.c
|
@ -117,7 +117,7 @@ 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 */
|
||||
char *text; /**< Text for the element */
|
||||
void *bitmap; /**< Bitmap for the element */
|
||||
struct node_element *next; /**< Next node element */
|
||||
unsigned int flag; /**< Client specified flag for data
|
||||
|
@ -233,26 +233,19 @@ struct tree *tree_create(unsigned int flags,
|
|||
const struct treeview_table *callbacks, void *client_data)
|
||||
{
|
||||
struct tree *tree;
|
||||
char *title;
|
||||
|
||||
tree = calloc(sizeof(struct tree), 1);
|
||||
if (tree == NULL) {
|
||||
LOG(("calloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
title = strdup("Root");
|
||||
if (title == NULL) {
|
||||
LOG(("malloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
free(tree);
|
||||
return NULL;
|
||||
}
|
||||
tree->root = tree_create_folder_node(NULL, NULL, title,
|
||||
tree->root = tree_create_folder_node(NULL,
|
||||
NULL,
|
||||
messages_get("Root"),
|
||||
false, false, false);
|
||||
if (tree->root == NULL) {
|
||||
free(title);
|
||||
free(tree);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -553,18 +546,7 @@ static void tree_recalculate_node_sizes(struct tree *tree, struct node *node,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a folder node with the specified title, and optionally links it into
|
||||
* the tree.
|
||||
*
|
||||
* \param tree the owner tree of 'parent', may be NULL
|
||||
* \param parent the parent node, or NULL not to link
|
||||
* \param title the node title (not copied, used directly)
|
||||
* \param editable if true, the node title will be editable
|
||||
* \param retain_in_memory if true, the node will stay in memory after deletion
|
||||
* \param deleted if true, the node is created with the deleted flag
|
||||
* \return the newly created node.
|
||||
*/
|
||||
/* exported interface documented in desktop/tree.h */
|
||||
struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
|
||||
const char *title, bool editable, bool retain_in_memory,
|
||||
bool deleted)
|
||||
|
@ -575,16 +557,20 @@ struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
|
|||
|
||||
node = calloc(sizeof(struct node), 1);
|
||||
if (node == NULL) {
|
||||
LOG(("calloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->data.text = strdup(title);
|
||||
if (node->data.text == NULL) {
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->folder = true;
|
||||
node->retain_in_memory = retain_in_memory;
|
||||
node->deleted = deleted;
|
||||
node->data.parent = node;
|
||||
node->data.type = NODE_ELEMENT_TEXT;
|
||||
node->data.text = title;
|
||||
node->data.flag = TREE_ELEMENT_TITLE;
|
||||
node->data.editable = editable;
|
||||
node->sort = NULL;
|
||||
|
@ -592,25 +578,14 @@ struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
|
|||
node->previous = NULL;
|
||||
|
||||
tree_recalculate_node_sizes(tree, node, true);
|
||||
if (parent != NULL)
|
||||
if (parent != NULL) {
|
||||
tree_link_node(tree, parent, node, false);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a leaf node with the specified title, and optionally links it into
|
||||
* the tree.
|
||||
*
|
||||
* \param tree the owner tree of 'parent', may be NULL
|
||||
* \param parent the parent node, or NULL not to link
|
||||
* \param title the node title (not copied, used directly)
|
||||
* \param editable if true, the node title will be editable
|
||||
* \param retain_in_memory if true, the node will stay in memory after deletion
|
||||
* \param deleted if true, the node is created with the deleted flag
|
||||
* \return the newly created node.
|
||||
*/
|
||||
/* exported interface documented in desktop/tree.h */
|
||||
struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
|
||||
const char *title, bool editable, bool retain_in_memory,
|
||||
bool deleted)
|
||||
|
@ -621,8 +596,12 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
|
|||
|
||||
node = calloc(sizeof(struct node), 1);
|
||||
if (node == NULL) {
|
||||
LOG(("calloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->data.text = strdup(title);
|
||||
if (node->data.text == NULL) {
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -631,7 +610,6 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
|
|||
node->deleted = deleted;
|
||||
node->data.parent = node;
|
||||
node->data.type = NODE_ELEMENT_TEXT;
|
||||
node->data.text = title;
|
||||
node->data.flag = TREE_ELEMENT_TITLE;
|
||||
node->data.editable = editable;
|
||||
node->sort = NULL;
|
||||
|
@ -639,8 +617,9 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
|
|||
node->previous = NULL;
|
||||
|
||||
tree_recalculate_node_sizes(tree, node, true);
|
||||
if (parent != NULL)
|
||||
if (parent != NULL) {
|
||||
tree_link_node(tree, parent, node, false);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -1502,18 +1481,20 @@ void tree_update_node_element(struct tree *tree, struct node_element *element,
|
|||
|
||||
assert(element != NULL);
|
||||
|
||||
if (tree != NULL && element == tree->editing)
|
||||
if ((tree != NULL) && (element == tree->editing)) {
|
||||
tree_stop_edit(tree, false);
|
||||
}
|
||||
|
||||
if (text != NULL && (element->type == NODE_ELEMENT_TEXT ||
|
||||
element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) {
|
||||
if ((text != NULL) &&
|
||||
(element->type == NODE_ELEMENT_TEXT ||
|
||||
element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) {
|
||||
if (element->text != NULL) {
|
||||
if(strcmp(element->text, text) == 0) text_changed = true;
|
||||
|
||||
if (strcmp(element->text, text) == 0) {
|
||||
text_changed = true;
|
||||
}
|
||||
response = NODE_CALLBACK_NOT_HANDLED;
|
||||
if (!element->editable &&
|
||||
element->parent->user_callback !=
|
||||
NULL) {
|
||||
if ((!element->editable) &&
|
||||
(element->parent->user_callback != NULL)) {
|
||||
msg_data.msg = NODE_DELETE_ELEMENT_TXT;
|
||||
msg_data.flag = element->flag;
|
||||
msg_data.node = element->parent;
|
||||
|
@ -1522,14 +1503,16 @@ void tree_update_node_element(struct tree *tree, struct node_element *element,
|
|||
element->parent->callback_data,
|
||||
&msg_data);
|
||||
}
|
||||
if (response != NODE_CALLBACK_HANDLED)
|
||||
free((void *)element->text);
|
||||
if (response != NODE_CALLBACK_HANDLED) {
|
||||
free(element->text);
|
||||
}
|
||||
}
|
||||
element->text = text;
|
||||
element->text = (char *)text;
|
||||
}
|
||||
|
||||
if (bitmap != NULL && (element->type == NODE_ELEMENT_BITMAP ||
|
||||
element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) {
|
||||
if ((bitmap != NULL) &&
|
||||
((element->type == NODE_ELEMENT_BITMAP) ||
|
||||
(element->type == NODE_ELEMENT_TEXT_PLUS_ICON))) {
|
||||
if (element->bitmap != NULL) {
|
||||
response = NODE_CALLBACK_NOT_HANDLED;
|
||||
if (element->parent->user_callback != NULL) {
|
||||
|
@ -1541,10 +1524,11 @@ void tree_update_node_element(struct tree *tree, struct node_element *element,
|
|||
element->parent->callback_data,
|
||||
&msg_data);
|
||||
}
|
||||
if (response != NODE_CALLBACK_HANDLED)
|
||||
|
||||
if (response != NODE_CALLBACK_HANDLED) {
|
||||
free(element->bitmap);
|
||||
}
|
||||
else {
|
||||
}
|
||||
} else {
|
||||
/* Increase the box width to accomodate the new icon */
|
||||
element->box.width += NODE_INSTEP;
|
||||
}
|
||||
|
|
|
@ -137,12 +137,39 @@ void tree_setup_colours(void);
|
|||
struct tree *tree_create(unsigned int flags,
|
||||
const struct treeview_table *callbacks,
|
||||
void *client_data);
|
||||
|
||||
/**
|
||||
* Creates a folder node with the specified title, and optionally links it into
|
||||
* the tree.
|
||||
*
|
||||
* \param tree the owner tree of 'parent', may be NULL
|
||||
* \param parent the parent node, or NULL not to link
|
||||
* \param title the node title
|
||||
* \param editable if true, the node title will be editable
|
||||
* \param retain_in_memory if true, the node will stay in memory after deletion
|
||||
* \param deleted if true, the node is created with the deleted flag
|
||||
* \return the newly created node or NULL on error.
|
||||
*/
|
||||
struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
|
||||
const char *title, bool editable, bool retain_in_memory,
|
||||
bool deleted);
|
||||
|
||||
/**
|
||||
* Creates a leaf node with the specified title, and optionally links it into
|
||||
* the tree.
|
||||
*
|
||||
* \param tree the owner tree of 'parent', may be NULL
|
||||
* \param parent the parent node, or NULL not to link
|
||||
* \param title the node title.
|
||||
* \param editable if true, the node title will be editable
|
||||
* \param retain_in_memory if true, the node will stay in memory after deletion
|
||||
* \param deleted if true, the node is created with the deleted flag
|
||||
* \return the newly created node or NULL on error.
|
||||
*/
|
||||
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,
|
||||
|
|
|
@ -126,35 +126,41 @@ void tree_url_node_cleanup()
|
|||
* \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
|
||||
* \param title custom title to use or NULL to use url
|
||||
* \return the node created, or NULL for failure
|
||||
*/
|
||||
struct node *tree_create_URL_node(struct tree *tree, struct node *parent,
|
||||
nsurl *url, const char *title,
|
||||
tree_node_user_callback user_callback, void *callback_data)
|
||||
{
|
||||
struct node *node;
|
||||
struct node *node = NULL;
|
||||
struct node_element *element;
|
||||
char *text_cp, *squashed;
|
||||
|
||||
squashed = squash_whitespace(title ? title : nsurl_access(url));
|
||||
text_cp = strdup(squashed);
|
||||
if (text_cp == NULL) {
|
||||
LOG(("malloc failed"));
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
if (title == NULL) {
|
||||
node = tree_create_leaf_node(tree,
|
||||
parent,
|
||||
nsurl_access(url),
|
||||
true, false, false);
|
||||
} else {
|
||||
char *squashed;
|
||||
|
||||
squashed = squash_whitespace(title);
|
||||
if (squashed != NULL) {
|
||||
node = tree_create_leaf_node(tree,
|
||||
parent,
|
||||
squashed,
|
||||
true, false, false);
|
||||
free(squashed);
|
||||
}
|
||||
}
|
||||
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)
|
||||
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);
|
||||
|
@ -165,7 +171,7 @@ struct node *tree_create_URL_node(struct tree *tree, struct node *parent,
|
|||
element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
|
||||
TREE_ELEMENT_URL, true);
|
||||
if (element != NULL) {
|
||||
text_cp = strdup(nsurl_access(url));
|
||||
char *text_cp = strdup(nsurl_access(url));
|
||||
if (text_cp == NULL) {
|
||||
tree_delete_node(tree, node, false);
|
||||
LOG(("malloc failed"));
|
||||
|
@ -194,22 +200,18 @@ struct node *tree_create_URL_node_readonly(struct tree *tree,
|
|||
{
|
||||
struct node *node;
|
||||
struct node_element *element;
|
||||
char *title;
|
||||
const char *title;
|
||||
|
||||
assert(url && data);
|
||||
|
||||
if (data->title != NULL) {
|
||||
title = strdup(data->title);
|
||||
title = data->title;
|
||||
} else {
|
||||
title = strdup(nsurl_access(url));
|
||||
title = nsurl_access(url);
|
||||
}
|
||||
|
||||
if (title == NULL)
|
||||
return NULL;
|
||||
|
||||
node = tree_create_leaf_node(tree, parent, title, false, false, false);
|
||||
if (node == NULL) {
|
||||
free(title);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -683,6 +685,7 @@ static bool tree_url_load_directory_cb(dom_node *node, void *ctx)
|
|||
|
||||
dir = tree_create_folder_node(tctx->tree, tctx->directory,
|
||||
title, true, false, false);
|
||||
free(title);
|
||||
if (dir == NULL) {
|
||||
dom_string_unref(name);
|
||||
return false;
|
||||
|
|
|
@ -188,6 +188,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="app_paintable">True</property>
|
||||
<property name="can_focus">False</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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -237,6 +237,7 @@
|
|||
<object class="GtkDrawingArea" id="hotlistDrawingArea">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -79,13 +79,13 @@
|
|||
</object>
|
||||
<object class="GtkAdjustment" id="layouthadjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="step_increment">30</property>
|
||||
<property name="page_increment">10</property>
|
||||
<property name="page_size">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="layoutvadjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="step_increment">30</property>
|
||||
<property name="page_increment">10</property>
|
||||
<property name="page_size">10</property>
|
||||
</object>
|
||||
|
|
132
gtk/window.c
132
gtk/window.c
|
@ -384,105 +384,91 @@ static gboolean nsgtk_window_button_release_event(GtkWidget *widget,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean nsgtk_window_scroll_event(GtkWidget *widget,
|
||||
GdkEventScroll *event, gpointer data)
|
||||
static gboolean
|
||||
nsgtk_window_scroll_event(GtkWidget *widget,
|
||||
GdkEventScroll *event,
|
||||
gpointer data)
|
||||
{
|
||||
struct gui_window *g = data;
|
||||
double value;
|
||||
double deltax = 0;
|
||||
double deltay = 0;
|
||||
GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
|
||||
GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
|
||||
GtkAllocation alloc;
|
||||
|
||||
LOG(("%d", event->direction));
|
||||
switch (event->direction) {
|
||||
case GDK_SCROLL_LEFT:
|
||||
if (browser_window_scroll_at_point(g->bw,
|
||||
event->x / g->bw->scale,
|
||||
event->y / g->bw->scale,
|
||||
-100, 0) != true) {
|
||||
/* core did not handle event do horizontal scroll */
|
||||
deltax = -1.0;
|
||||
break;
|
||||
|
||||
value = gtk_adjustment_get_value(hscroll) -
|
||||
(nsgtk_adjustment_get_step_increment(hscroll) *2);
|
||||
case GDK_SCROLL_UP:
|
||||
deltay = -1.0;
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_RIGHT:
|
||||
deltax = 1.0;
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_DOWN:
|
||||
deltay = 1.0;
|
||||
break;
|
||||
|
||||
#if GTK_CHECK_VERSION(3,4,0)
|
||||
case GDK_SCROLL_SMOOTH:
|
||||
gdk_event_get_scroll_deltas((GdkEvent *)event, &deltax, &deltay);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG(("Unhandled mouse scroll direction"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
deltax *= nsgtk_adjustment_get_step_increment(hscroll);
|
||||
deltay *= nsgtk_adjustment_get_step_increment(vscroll);
|
||||
|
||||
LOG(("Scrolling %f, %f", deltax, deltay));
|
||||
|
||||
if (browser_window_scroll_at_point(g->bw,
|
||||
event->x / g->bw->scale,
|
||||
event->y / g->bw->scale,
|
||||
deltax, deltay) != true) {
|
||||
|
||||
/* core did not handle event so change adjustments */
|
||||
|
||||
/* Horizontal */
|
||||
if (deltax != 0) {
|
||||
value = gtk_adjustment_get_value(hscroll) + deltax;
|
||||
|
||||
/* @todo consider gtk_widget_get_allocated_width() */
|
||||
nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
|
||||
|
||||
if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) {
|
||||
value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;
|
||||
}
|
||||
if (value < nsgtk_adjustment_get_lower(hscroll)) {
|
||||
value = nsgtk_adjustment_get_lower(hscroll);
|
||||
}
|
||||
|
||||
gtk_adjustment_set_value(hscroll, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_UP:
|
||||
if (browser_window_scroll_at_point(g->bw,
|
||||
event->x / g->bw->scale,
|
||||
event->y / g->bw->scale,
|
||||
0, -100) != true) {
|
||||
/* core did not handle event change vertical
|
||||
* adjustment.
|
||||
*/
|
||||
/* Vertical */
|
||||
if (deltay != 0) {
|
||||
value = gtk_adjustment_get_value(vscroll) + deltay;
|
||||
|
||||
value = gtk_adjustment_get_value(vscroll) -
|
||||
(nsgtk_adjustment_get_step_increment(vscroll) * 2);
|
||||
/* @todo consider gtk_widget_get_allocated_height */
|
||||
nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
|
||||
|
||||
if (value > (nsgtk_adjustment_get_upper(vscroll) - alloc.height)) {
|
||||
value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
|
||||
}
|
||||
if (value < nsgtk_adjustment_get_lower(vscroll)) {
|
||||
value = nsgtk_adjustment_get_lower(vscroll);
|
||||
}
|
||||
|
||||
gtk_adjustment_set_value(vscroll, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_RIGHT:
|
||||
if (browser_window_scroll_at_point(g->bw,
|
||||
event->x / g->bw->scale,
|
||||
event->y / g->bw->scale,
|
||||
100, 0) != true) {
|
||||
|
||||
/* core did not handle event change horizontal
|
||||
* adjustment.
|
||||
*/
|
||||
|
||||
value = gtk_adjustment_get_value(hscroll) +
|
||||
(nsgtk_adjustment_get_step_increment(hscroll) * 2);
|
||||
|
||||
/* @todo consider gtk_widget_get_allocated_width() */
|
||||
nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
|
||||
|
||||
if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) {
|
||||
value = nsgtk_adjustment_get_upper(hscroll) -
|
||||
alloc.width;
|
||||
}
|
||||
|
||||
gtk_adjustment_set_value(hscroll, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_DOWN:
|
||||
if (browser_window_scroll_at_point(g->bw,
|
||||
event->x / g->bw->scale,
|
||||
event->y / g->bw->scale,
|
||||
0, 100) != true) {
|
||||
/* core did not handle event change vertical
|
||||
* adjustment.
|
||||
*/
|
||||
|
||||
value = gtk_adjustment_get_value(vscroll) +
|
||||
(nsgtk_adjustment_get_step_increment(vscroll) * 2);
|
||||
/* @todo consider gtk_widget_get_allocated_height */
|
||||
nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
|
||||
|
||||
if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height) {
|
||||
value = nsgtk_adjustment_get_upper(vscroll) -
|
||||
alloc.height;
|
||||
}
|
||||
|
||||
gtk_adjustment_set_value(vscroll, value);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -2334,7 +2334,7 @@ nl.all.SSLCerts:SSL certificates
|
|||
en.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.
|
||||
de.all.SSLError:NetSurf konnte ein SSL Zertifikat nicht prüfen. Bitte die Details unten beachten.
|
||||
fr.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.
|
||||
it.all.SSLError:NetSurf non è stato in grado di verificare l'autenticità di questo certificato SSL, per favore verifica i dettagli presenti di seguito
|
||||
it.all.SSLError:NetSurf non è stato in grado di verificare l'autenticità di questo certificato SSL, per favore verifica i dettagli presenti di seguito
|
||||
nl.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.
|
||||
en.all.SSL_Certificate_Subject:Subject: %s
|
||||
de.all.SSL_Certificate_Subject:Subject: %s
|
||||
|
@ -2744,7 +2744,7 @@ nl.all.HotlistSaveError:The hotlist was unable to be correctly saved.
|
|||
en.all.TreeLoadError:The tree was unable to be correctly loaded.
|
||||
de.all.TreeLoadError:The tree was unable to be correctly loaded.
|
||||
fr.all.TreeLoadError:The tree was unable to be correctly loaded.
|
||||
it.all.TreeLoadError:L'albero non è stato caricato correttamente.
|
||||
it.all.TreeLoadError:L'albero non è stato caricato correttamente.
|
||||
nl.all.TreeLoadError:The tree was unable to be correctly loaded.
|
||||
en.all.NoDirError:%s is not a directory
|
||||
de.all.NoDirError:%s ist kein Verzeichnis.
|
||||
|
@ -5011,7 +5011,7 @@ nl.ro.HelpInterfaceConfig13:\Ssave these settings and close the \w.|M\Asave thes
|
|||
en.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
de.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
fr.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
it.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
it.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
nl.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
|
||||
en.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
|
||||
de.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright © 2013 Vincent Sanders <vince@netsurf-browser.org>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# * The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
=head1
|
||||
|
||||
retrive resource from transifex service
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Getopt::Long ();
|
||||
use LWP::UserAgent;
|
||||
use JSON qw( decode_json );
|
||||
use Data::Dumper;
|
||||
use Fcntl qw( O_CREAT O_EXCL O_WRONLY O_APPEND O_RDONLY O_WRONLY );
|
||||
|
||||
use constant GETOPT_OPTS => qw( auto_abbrev no_getopt_compat bundling );
|
||||
use constant GETOPT_SPEC =>
|
||||
qw( output|o=s
|
||||
lang|l=s
|
||||
resource|res|r=s
|
||||
project|prj|p=s
|
||||
user|u=s
|
||||
password|w=s
|
||||
help|h|? );
|
||||
|
||||
# default option values:
|
||||
my %opt = qw( resource messagesany project netsurf user netsurf );
|
||||
|
||||
sub output_stream ();
|
||||
sub usage ();
|
||||
|
||||
sub main ()
|
||||
{
|
||||
my $output;
|
||||
my $opt_ok;
|
||||
|
||||
# option parsing:
|
||||
Getopt::Long::Configure( GETOPT_OPTS );
|
||||
$opt_ok = Getopt::Long::GetOptions( \%opt, GETOPT_SPEC );
|
||||
|
||||
if( $opt_ok )
|
||||
{
|
||||
$output = output_stream();
|
||||
}
|
||||
|
||||
# double check the options are sane (and we weren't asked for the help)
|
||||
if( !$opt_ok || $opt{help} || $opt{lang} !~ /^[a-z]{2}$/ )
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
my $transifexurl = "https://www.transifex.com/api/2/project/" . $opt{project} . "/resource/" . $opt{resource} . "/translation/" . $opt{lang} . "/";
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->credentials(
|
||||
'www.transifex.com:443',
|
||||
'Transifex API',
|
||||
$opt{user} => $opt{password}
|
||||
);
|
||||
|
||||
my $response = $ua->get( $transifexurl );
|
||||
if (!$response->is_success) {
|
||||
die $response->status_line . " When fetching " . $transifexurl;
|
||||
}
|
||||
|
||||
# Decode the entire JSON
|
||||
my $decoded_json = decode_json( $response->decoded_content );
|
||||
|
||||
print ( $output $decoded_json->{'content'} );
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
sub usage ()
|
||||
{
|
||||
print(STDERR <<TXT );
|
||||
usage:
|
||||
$0 -l lang-code \
|
||||
[-o output-file] [-r resource] [-p project] [-u user] [-w password]
|
||||
|
||||
lang-code : en fr ko ... (no default)
|
||||
project : transifex project (default 'netsurf')
|
||||
resource : transifex resource (default 'messagesany')
|
||||
user : transifex resource (default 'netsurf')
|
||||
password : transifex resource (no default)
|
||||
output-file: defaults to standard output
|
||||
TXT
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub output_stream ()
|
||||
{
|
||||
if( $opt{output} )
|
||||
{
|
||||
my $ofh;
|
||||
|
||||
sysopen( $ofh, $opt{output}, O_CREAT|O_EXCL|O_APPEND|O_WRONLY ) ||
|
||||
die( "$0: Failed to open output file $opt{output}: $!\n" );
|
||||
|
||||
return $ofh;
|
||||
}
|
||||
|
||||
return \*STDOUT;
|
||||
}
|
|
@ -89,21 +89,13 @@ char *filepath_sfindfile(char *str, const char *format, ...)
|
|||
/* exported interface documented in filepath.h */
|
||||
char *filepath_findfile(const char *format, ...)
|
||||
{
|
||||
char *str;
|
||||
char *ret;
|
||||
va_list ap;
|
||||
|
||||
str = malloc(PATH_MAX);
|
||||
if (str == NULL)
|
||||
return NULL; /* unable to allocate memory */
|
||||
|
||||
va_start(ap, format);
|
||||
ret = filepath_vsfindfile(str, format, ap);
|
||||
ret = filepath_vsfindfile(NULL, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret == NULL)
|
||||
free(str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright © 2013 Vivek Dasmohapatra <vivek@collabora.co.uk>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# * The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
=head1
|
||||
|
||||
Take a single-language messages file and merge it back in to the
|
||||
NetSurf master messaged (i10n) file.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
|
||||
use Getopt::Long ();
|
||||
use Fcntl qw( O_CREAT O_EXCL O_WRONLY O_APPEND O_RDONLY O_WRONLY O_TRUNC );
|
||||
|
||||
use constant GETOPT_OPTS => qw( auto_abbrev no_getopt_compat bundling );
|
||||
use constant GETOPT_SPEC =>
|
||||
qw( output|o=s
|
||||
input|i=s
|
||||
lang|l=s
|
||||
plat|platform|p=s
|
||||
format|fmt|f=s
|
||||
import|I=s
|
||||
help|h|? );
|
||||
|
||||
# default option values:
|
||||
my %opt = qw( plat any format messages );
|
||||
|
||||
sub input_stream ($;$);
|
||||
sub output_stream ();
|
||||
sub usage ();
|
||||
sub parser ();
|
||||
|
||||
sub main ()
|
||||
{
|
||||
my $input;
|
||||
my $output;
|
||||
my $import;
|
||||
my $parser;
|
||||
my $opt_ok;
|
||||
my @input;
|
||||
my %message;
|
||||
|
||||
# option parsing:
|
||||
Getopt::Long::Configure( GETOPT_OPTS );
|
||||
$opt_ok = Getopt::Long::GetOptions( \%opt, GETOPT_SPEC );
|
||||
|
||||
# allow input, import & output to be specified as non-option arguments:
|
||||
if( @ARGV ) { $opt{input } ||= shift( @ARGV ) }
|
||||
if( @ARGV ) { $opt{import} ||= shift( @ARGV ) }
|
||||
if( @ARGV ) { $opt{output} ||= shift( @ARGV ) }
|
||||
|
||||
# open the appropriate streams and get the formatter and headers:
|
||||
if( $opt_ok )
|
||||
{
|
||||
$input = input_stream( $opt{input} );
|
||||
$import = input_stream( $opt{import}, 'import-file' );
|
||||
$parser = parser();
|
||||
$opt{plat} ||= 'any';
|
||||
}
|
||||
|
||||
# double check the options are sane (and we weren't asked for the help)
|
||||
if( !$opt_ok || $opt{help} || $opt{lang} !~ /^[a-z]{2}$/ )
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
@input = <$input>;
|
||||
$output = output_stream();
|
||||
|
||||
$parser->( \%message, $import );
|
||||
|
||||
foreach ( @input )
|
||||
{
|
||||
use bytes;
|
||||
|
||||
if( !/#/ &&
|
||||
!/^\s*$/ &&
|
||||
/^([a-z]{2})\.([^.]+)\.([^:]+):/ )
|
||||
{
|
||||
my( $lang, $plat, $key ) = ( $1, $2, $3 );
|
||||
|
||||
if( $lang eq $opt{lang} )
|
||||
{
|
||||
my $val = $message{ $key };
|
||||
if( $val &&
|
||||
( $opt{plat} eq 'any' || # all platforms ok
|
||||
$opt{plat} eq $plat ) ) # specified platform matched
|
||||
{
|
||||
print( $output $val ? qq|$1.$2.$3:$val\n| : $_ );
|
||||
next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print( $output $_ );
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
sub usage ()
|
||||
{
|
||||
my @fmt = map { s/::$//; $_ } keys(%{$::{'msgfmt::'}});
|
||||
print( STDERR <<TXT );
|
||||
usage:
|
||||
$0 -l lang-code \
|
||||
[-p platform] [-f format] \
|
||||
[-o output-file] [-i input-file] [-I import-file]
|
||||
|
||||
$0 -l lang-code … [input-file [import-file [output-file]]]
|
||||
|
||||
lang-code : en fr ko … (no default)
|
||||
platform : any gtk ami (default 'any')
|
||||
format : @fmt (default 'messages')
|
||||
input-file : defaults to standard input
|
||||
output-file: defaults to standard output
|
||||
import-file: no default
|
||||
|
||||
The input-file may be the same as the output-file, in which case
|
||||
it will be altered in place.
|
||||
TXT
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub input_stream ($;$)
|
||||
{
|
||||
my $file = shift();
|
||||
my $must_exist = shift();
|
||||
|
||||
if( $file )
|
||||
{
|
||||
my $ifh;
|
||||
|
||||
sysopen( $ifh, $file, O_RDONLY ) ||
|
||||
die( "$0: Failed to open input file $file: $!\n" );
|
||||
|
||||
return $ifh;
|
||||
}
|
||||
|
||||
if( $must_exist )
|
||||
{
|
||||
print( STDERR "No file specified for $must_exist\n" );
|
||||
usage();
|
||||
}
|
||||
|
||||
return \*STDIN;
|
||||
}
|
||||
|
||||
sub output_stream ()
|
||||
{
|
||||
if( $opt{output} )
|
||||
{
|
||||
my $ofh;
|
||||
|
||||
sysopen( $ofh, $opt{output}, O_CREAT|O_TRUNC|O_WRONLY ) ||
|
||||
die( "$0: Failed to open output file $opt{output}: $!\n" );
|
||||
|
||||
return $ofh;
|
||||
}
|
||||
|
||||
return \*STDOUT;
|
||||
}
|
||||
|
||||
sub parser ()
|
||||
{
|
||||
my $name = $opt{format};
|
||||
my $func = "msgfmt::$name"->UNIVERSAL::can("parse");
|
||||
|
||||
return $func || die( "No handler found for format '$name'\n" );
|
||||
}
|
||||
|
||||
# format implementations:
|
||||
{
|
||||
package msgfmt::java;
|
||||
|
||||
sub unescape { $_[0] =~ s/\\([\\':])/$1/g; $_[0] }
|
||||
sub parse
|
||||
{
|
||||
my $cache = shift();
|
||||
my $stream = shift();
|
||||
|
||||
while ( <$stream> )
|
||||
{
|
||||
if( /(\S+)\s*=\s?(.*)/ )
|
||||
{
|
||||
my $key = $1;
|
||||
my $val = $2;
|
||||
$cache->{ $key } = unescape( $val );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
package msgfmt::messages; # native netsurf format
|
||||
|
||||
sub parse
|
||||
{
|
||||
my $cache = shift();
|
||||
my $stream = shift();
|
||||
|
||||
while ( <$stream> )
|
||||
{
|
||||
if( /^([a-z]{2})\.([^.]+)\.([^:]+):(.*)/ )
|
||||
{
|
||||
my( $lang, $plat, $key, $val ) = ( $1, $2, $3, $4 );
|
||||
|
||||
if( $lang ne $opt{lang} ) { next }
|
||||
if( $opt{plat} ne 'any' &&
|
||||
$opt{plat} ne $plat &&
|
||||
'all' ne $plat ) { next }
|
||||
|
||||
$cache->{ $key } = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
package msgfmt::transifex;
|
||||
use base 'msgfmt::java';
|
||||
|
||||
# the differences between transifex and java properties only matter in
|
||||
# the outward direction: During import they can be treated the same way
|
||||
}
|
||||
|
||||
{
|
||||
package msgfmt::android;
|
||||
|
||||
ANDROID_XML:
|
||||
{
|
||||
package msgfmt::android::xml;
|
||||
|
||||
my @stack;
|
||||
my $data;
|
||||
my $key;
|
||||
our $cache;
|
||||
|
||||
sub StartDocument ($) { @stack = (); $key = '' }
|
||||
sub Text ($) { if( $key ) { $data .= $_ } }
|
||||
sub PI ($$$) { }
|
||||
sub EndDocument ($) { }
|
||||
|
||||
sub EndTag ($$)
|
||||
{
|
||||
pop( @stack );
|
||||
|
||||
if( !$key ) { return; }
|
||||
|
||||
$cache->{ $key } = $data;
|
||||
$data = $key = '';
|
||||
}
|
||||
|
||||
sub StartTag ($$)
|
||||
{
|
||||
push( @stack, $_[1] );
|
||||
|
||||
if( "@stack" eq "resources string" )
|
||||
{
|
||||
$data = '';
|
||||
$key = $_{ name };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse
|
||||
{
|
||||
require XML::Parser;
|
||||
|
||||
if( !$XML::Parser::VERSION )
|
||||
{
|
||||
die("XML::Parser required for android format support\n");
|
||||
}
|
||||
|
||||
$msgfmt::android::xml::cache = shift();
|
||||
my $stream = shift();
|
||||
my $parser = XML::Parser->new( Style => 'Stream',
|
||||
Pkg => 'msgfmt::android::xml' );
|
||||
$parser->parse( $stream );
|
||||
}
|
||||
}
|
|
@ -98,26 +98,34 @@ char *remove_underscores(const char *s, bool replacespace)
|
|||
/**
|
||||
* Replace consecutive whitespace with a single space.
|
||||
*
|
||||
* @todo determine if squash_whitespace utf-8 safe and that it needs to be
|
||||
*
|
||||
* \param s source string
|
||||
* \return heap allocated result, or 0 on memory exhaustion
|
||||
* \return heap allocated result, or NULL on memory exhaustion
|
||||
*/
|
||||
|
||||
char * squash_whitespace(const char *s)
|
||||
char *squash_whitespace(const char *s)
|
||||
{
|
||||
char *c = malloc(strlen(s) + 1);
|
||||
char *c;
|
||||
int i = 0, j = 0;
|
||||
if (!c)
|
||||
return 0;
|
||||
do {
|
||||
if (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' ||
|
||||
s[i] == '\t') {
|
||||
c[j++] = ' ';
|
||||
while (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' ||
|
||||
s[i] == '\t')
|
||||
i++;
|
||||
}
|
||||
c[j++] = s[i++];
|
||||
} while (s[i - 1] != 0);
|
||||
|
||||
c = malloc(strlen(s) + 1);
|
||||
if (c != NULL) {
|
||||
do {
|
||||
if (s[i] == ' ' ||
|
||||
s[i] == '\n' ||
|
||||
s[i] == '\r' ||
|
||||
s[i] == '\t') {
|
||||
c[j++] = ' ';
|
||||
while (s[i] == ' ' ||
|
||||
s[i] == '\n' ||
|
||||
s[i] == '\r' ||
|
||||
s[i] == '\t')
|
||||
i++;
|
||||
}
|
||||
c[j++] = s[i++];
|
||||
} while (s[i - 1] != 0);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue