19 |
|
|
20 |
#include "gpxview.h" |
#include "gpxview.h" |
21 |
|
|
22 |
|
// #undef PANNABLE_HTML |
23 |
|
|
24 |
|
#ifdef FREMANTLE |
25 |
|
#include <hildon/hildon-banner.h> |
26 |
|
#include <hildon/hildon-note.h> |
27 |
|
#endif |
28 |
|
|
29 |
typedef struct load_context { |
typedef struct load_context { |
30 |
int active; |
int active; |
31 |
GMutex *mutex; |
GMutex *mutex; |
145 |
return NULL; |
return NULL; |
146 |
} |
} |
147 |
|
|
148 |
|
#ifdef ENABLE_BROWSER_INTERFACE |
149 |
|
static void on_link_clicked(GtkHTML *html, const gchar *url, |
150 |
|
gpointer data) { |
151 |
|
|
152 |
|
appdata_t *appdata = (appdata_t*)data; |
153 |
|
|
154 |
|
#if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5) |
155 |
|
GtkWidget *dialog = gtk_message_dialog_new( |
156 |
|
GTK_WINDOW(appdata->window), |
157 |
|
GTK_DIALOG_DESTROY_WITH_PARENT, |
158 |
|
GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, |
159 |
|
_("Open link in external browser?")); |
160 |
|
gboolean yes = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES); |
161 |
|
#else |
162 |
|
GtkWidget *dialog = |
163 |
|
hildon_note_new_confirmation(GTK_WINDOW(appdata->window), |
164 |
|
_("Open link in external browser?")); |
165 |
|
gboolean yes = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK); |
166 |
|
#endif |
167 |
|
|
168 |
|
gtk_widget_destroy(dialog); |
169 |
|
|
170 |
|
if(yes) |
171 |
|
browser_url(appdata, (char*)url); |
172 |
|
} |
173 |
|
#endif |
174 |
|
|
175 |
static void on_request_url(GtkHTML *html, const gchar *url, |
static void on_request_url(GtkHTML *html, const gchar *url, |
176 |
GtkHTMLStream *stream, gpointer data) { |
GtkHTMLStream *stream, gpointer data) { |
177 |
char buffer[4096]; |
char buffer[4096]; |
178 |
GnomeVFSFileSize bytes_read; |
GnomeVFSFileSize bytes_read; |
179 |
|
|
180 |
http_context_t *context = (http_context_t*)data; |
http_context_t *context = (http_context_t*)data; |
181 |
|
|
182 |
if(context->cache) { |
if(context->cache) { |
212 |
fclose(f); |
fclose(f); |
213 |
|
|
214 |
} else { |
} else { |
215 |
if(context->appdata->load_images) { |
printf("image file doesn't exist, starting extra thread!\n"); |
|
printf("image file doesn't exist, starting extra thread!\n"); |
|
|
|
|
|
checkdir(path); |
|
|
|
|
|
/* walk to end of list */ |
|
|
load_context_t **load_context = &(context->load_context); |
|
|
while(*load_context) |
|
|
load_context = &(*load_context)->next; |
|
|
|
|
|
*load_context = g_new0(load_context_t, 1); |
|
|
|
|
|
(*load_context)->url = strdup(url); |
|
|
(*load_context)->path = strdup(path); |
|
|
(*load_context)->view = context->view; |
|
|
(*load_context)->stream = stream; |
|
|
(*load_context)->next = NULL; |
|
|
(*load_context)->active = TRUE; |
|
|
(*load_context)->mutex = g_mutex_new(); |
|
216 |
|
|
217 |
g_thread_create(loader_thread, *load_context, TRUE, NULL); |
checkdir(path); |
218 |
return; |
|
219 |
} else |
/* walk to end of list */ |
220 |
g_print("Image loading disabled\n"); |
load_context_t **load_context = &(context->load_context); |
221 |
|
while(*load_context) |
222 |
|
load_context = &(*load_context)->next; |
223 |
|
|
224 |
|
*load_context = g_new0(load_context_t, 1); |
225 |
|
|
226 |
|
(*load_context)->url = strdup(url); |
227 |
|
(*load_context)->path = strdup(path); |
228 |
|
(*load_context)->view = context->view; |
229 |
|
(*load_context)->stream = stream; |
230 |
|
(*load_context)->next = NULL; |
231 |
|
(*load_context)->active = TRUE; |
232 |
|
(*load_context)->mutex = g_mutex_new(); |
233 |
|
|
234 |
|
g_thread_create(loader_thread, *load_context, TRUE, NULL); |
235 |
|
return; |
236 |
} |
} |
237 |
} else { |
} else { |
238 |
/* not a cache, maybe help, so load images from icon directory */ |
/* not a cache, maybe help, so load images from icon directory */ |
381 |
} |
} |
382 |
#endif |
#endif |
383 |
|
|
384 |
/* panning a gtkhtml view currently doesn't work well */ |
#ifdef FREMANTLE |
385 |
#undef PANNABLE_HTML |
static void |
386 |
|
tap_and_hold_cb (GtkWidget *widget, gpointer user_data) { |
387 |
|
appdata_t *appdata = (appdata_t*)user_data; |
388 |
|
|
389 |
|
/* the HildonTextView becomes semi-copy'n pasteable if we enable */ |
390 |
|
/* the cursor */ |
391 |
|
if(GTK_WIDGET_TYPE(widget) == HILDON_TYPE_TEXT_VIEW) { |
392 |
|
gboolean state = gtk_text_view_get_cursor_visible(GTK_TEXT_VIEW(widget)); |
393 |
|
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(widget), !state); |
394 |
|
return; |
395 |
|
} |
396 |
|
|
397 |
|
#if 0 |
398 |
|
GtkWidget *parent = widget->parent; |
399 |
|
|
400 |
|
/* check if the parent actually is a hildonpannablearea */ |
401 |
|
if(GTK_WIDGET_TYPE(parent) != HILDON_TYPE_PANNABLE_AREA) { |
402 |
|
printf("parent is not pannable area, ignoring event\n"); |
403 |
|
return; |
404 |
|
} |
405 |
|
|
406 |
|
gboolean enabled = FALSE; |
407 |
|
g_object_get(parent, "enabled", &enabled, NULL); |
408 |
|
enabled = !enabled; |
409 |
|
g_object_set(parent, "enabled", enabled, NULL); |
410 |
|
|
411 |
#ifdef PANNABLE_HTML |
hildon_banner_show_information(GTK_WIDGET(appdata->window), |
412 |
/* eat the button events */ |
NULL, enabled?"enabled":"disabled"); |
413 |
static gboolean on_button_press(GtkWidget *widget, GdkEventButton *event, |
#endif |
|
gpointer user_data) { |
|
|
return TRUE; |
|
414 |
} |
} |
415 |
#endif |
#endif |
416 |
|
|
421 |
static const char *html_end = "</body></html>"; |
static const char *html_end = "</body></html>"; |
422 |
|
|
423 |
GtkWidget *html_view(appdata_t *appdata, char *text, |
GtkWidget *html_view(appdata_t *appdata, char *text, |
424 |
gboolean is_html, gboolean scrollwin, |
html_mode_t mode, gboolean scrollwin, |
425 |
cache_t *cache, char *anchor) { |
cache_t *cache, char *anchor) { |
426 |
GtkWidget *view; |
GtkWidget *view; |
427 |
|
|
428 |
if(is_html) { |
if(mode == HTML_HTML) { |
429 |
http_context_t *context = g_new0(http_context_t, 1); |
http_context_t *context = g_new0(http_context_t, 1); |
430 |
context->appdata = appdata; |
context->appdata = appdata; |
431 |
context->cache = cache; |
context->cache = cache; |
432 |
|
|
433 |
context->view = view = gtk_html_new(); |
context->view = view = gtk_html_new(); |
434 |
|
|
435 |
|
#ifndef PANNABLE_HTML |
436 |
|
// gtk_html_set_auto_panning(GTK_HTML(view), TRUE); |
437 |
|
#else |
438 |
|
gtk_html_set_auto_panning(GTK_HTML(view), FALSE); |
439 |
|
#endif |
440 |
|
|
441 |
|
#ifdef FREMANTLE |
442 |
|
/* allow selection does not allow anything, but disables auto panning ... */ |
443 |
|
/* even worse: frequently causes the device to reboot */ |
444 |
|
// gtk_html_allow_selection(GTK_HTML(view), TRUE); |
445 |
|
#endif |
446 |
|
|
447 |
/* create a callback to load images only if a cache has been given */ |
/* create a callback to load images only if a cache has been given */ |
448 |
/* so that images can be cached/stored appropriately */ |
/* so that images can be cached/stored appropriately */ |
449 |
g_signal_connect(G_OBJECT(view), "url_requested", |
g_signal_connect(G_OBJECT(view), "url_requested", |
450 |
G_CALLBACK(on_request_url), context); |
G_CALLBACK(on_request_url), context); |
451 |
|
|
452 |
|
#ifdef ENABLE_BROWSER_INTERFACE |
453 |
|
g_signal_connect(G_OBJECT(view), "link_clicked", |
454 |
|
G_CALLBACK(on_link_clicked), context->appdata); |
455 |
|
#endif |
456 |
|
|
457 |
GtkHTMLStream *stream = gtk_html_begin(GTK_HTML(view)); |
GtkHTMLStream *stream = gtk_html_begin(GTK_HTML(view)); |
458 |
|
|
459 |
gtk_html_write(GTK_HTML(view), stream, html_start, strlen(html_start)); |
gtk_html_write(GTK_HTML(view), stream, html_start, strlen(html_start)); |
474 |
*h = g_new0(struct html_view, 1); |
*h = g_new0(struct html_view, 1); |
475 |
(*h)->view = view; |
(*h)->view = view; |
476 |
|
|
477 |
#ifdef PANNABLE_HTML |
#ifdef FREMANTLE |
478 |
/* this causes finger scrolling to work nicely but also prevents */ |
gtk_widget_tap_and_hold_setup(GTK_WIDGET(view), NULL, NULL, 0); |
479 |
/* copy'n paste from working correctly */ |
g_signal_connect(G_OBJECT(view), "tap-and-hold", |
480 |
gtk_widget_set_sensitive(GTK_WIDGET(view), FALSE); |
G_CALLBACK(tap_and_hold_cb), appdata); |
|
|
|
|
g_signal_connect(G_OBJECT(view), "button-press-event", |
|
|
G_CALLBACK(on_button_press), NULL); |
|
481 |
#endif |
#endif |
482 |
|
|
483 |
g_signal_connect(G_OBJECT(view), "destroy", |
g_signal_connect(G_OBJECT(view), "destroy", |
491 |
#else |
#else |
492 |
view = hildon_text_view_new(); |
view = hildon_text_view_new(); |
493 |
hildon_text_view_set_buffer(HILDON_TEXT_VIEW(view), buffer); |
hildon_text_view_set_buffer(HILDON_TEXT_VIEW(view), buffer); |
494 |
|
|
495 |
|
gtk_widget_tap_and_hold_setup(GTK_WIDGET(view), NULL, NULL, 0); |
496 |
|
g_signal_connect(G_OBJECT(view), "tap-and-hold", |
497 |
|
G_CALLBACK(tap_and_hold_cb), appdata); |
498 |
#endif |
#endif |
499 |
|
|
500 |
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD); |
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD); |
501 |
gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE); |
gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE); |
502 |
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view), FALSE); |
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view), FALSE); |
503 |
|
|
504 |
|
/* make this look nicer in fremantle and not just black-on-white */ |
505 |
|
/* just use the default style */ |
506 |
|
#ifdef USE_STACKABLE_WINDOW |
507 |
|
/* in fremantle this is really tricky and we need to inherit the */ |
508 |
|
/* style from the topmost window in the stack */ |
509 |
|
HildonWindowStack *stack = hildon_window_stack_get_default(); |
510 |
|
GList *list = hildon_window_stack_get_windows(stack); |
511 |
|
gtk_widget_set_style(view, GTK_WIDGET(list->data)->style); |
512 |
|
g_list_free(list); |
513 |
|
#else |
514 |
|
gtk_widget_set_style(view, GTK_WIDGET(appdata->window)->style); |
515 |
|
#endif |
516 |
|
|
517 |
#ifndef NO_COPY_N_PASTE |
#ifndef NO_COPY_N_PASTE |
518 |
g_signal_connect(G_OBJECT(view), "destroy", |
g_signal_connect(G_OBJECT(view), "destroy", |
519 |
G_CALLBACK(on_destroy_textview), appdata); |
G_CALLBACK(on_destroy_textview), appdata); |
532 |
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
533 |
gtk_container_add(GTK_CONTAINER(scrolled_window), view); |
gtk_container_add(GTK_CONTAINER(scrolled_window), view); |
534 |
|
|
|
#if 1 |
|
535 |
return scrolled_window; |
return scrolled_window; |
536 |
#else |
#else |
|
GtkWidget *fixed = gtk_fixed_new(); |
|
|
gtk_fixed_put(GTK_FIXED(fixed), scrolled_window, 0, 0); |
|
|
GtkWidget *tbutton = gtk_toggle_button_new_with_label("sel"); |
|
|
gtk_fixed_put(GTK_FIXED(fixed), tbutton, 0, 0); |
|
|
return fixed; |
|
|
#endif |
|
|
#else |
|
537 |
#ifndef PANNABLE_HTML |
#ifndef PANNABLE_HTML |
538 |
if(is_html) { |
if(mode == HTML_HTML) { |
539 |
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); |
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); |
540 |
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window), |
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window), |
541 |
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |