implement more toolbar item handlers and make menus call them

This commit is contained in:
Vincent Sanders 2019-08-28 22:32:15 +01:00 committed by Daniel Silverstone
parent 8eebe695f0
commit 8f0c0734ea
6 changed files with 431 additions and 361 deletions

View File

@ -142,21 +142,23 @@ nsgtk_menu_add_image_item(GtkMenu *menu,
static struct nsgtk_export_submenu * static struct nsgtk_export_submenu *
nsgtk_menu_export_submenu(GtkAccelGroup *group) nsgtk_menu_export_submenu(GtkAccelGroup *group)
{ {
struct nsgtk_export_submenu *ret = malloc(sizeof(struct struct nsgtk_export_submenu *ret;
nsgtk_export_submenu)); ret = malloc(sizeof(struct nsgtk_export_submenu));
if (ret == NULL) { if (ret == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0); nsgtk_warning(messages_get("NoMemory"), 0);
return NULL; return NULL;
} }
ret->export_menu = GTK_MENU(gtk_menu_new()); ret->export_menu = GTK_MENU(gtk_menu_new());
if (ret->export_menu == NULL) { if (ret->export_menu == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0); nsgtk_warning(messages_get("NoMemory"), 0);
free(ret); free(ret);
return NULL; return NULL;
} }
IMAGE_ITEM(export, savepage, gtkSavePage, ret, group);
IMAGE_ITEM(export, plaintext, gtkPlainText, ret, group); IMAGE_ITEM(export, plaintext, gtkPlainText, ret, group);
IMAGE_ITEM(export, drawfile, gtkDrawFile, ret, group);
IMAGE_ITEM(export, postscript, gtkPostScript, ret, group);
IMAGE_ITEM(export, pdf, gtkPDF, ret, group); IMAGE_ITEM(export, pdf, gtkPDF, ret, group);
return ret; return ret;
} }
@ -323,7 +325,6 @@ static struct nsgtk_file_menu *nsgtk_menu_file_submenu(GtkAccelGroup *group)
IMAGE_ITEM(file, openfile, gtkOpenFile, fmenu, group); IMAGE_ITEM(file, openfile, gtkOpenFile, fmenu, group);
IMAGE_ITEM(file, closewindow, gtkCloseWindow, fmenu, group); IMAGE_ITEM(file, closewindow, gtkCloseWindow, fmenu, group);
ADD_SEP(file, fmenu); ADD_SEP(file, fmenu);
IMAGE_ITEM(file, savepage, gtkSavePage, fmenu, group);
IMAGE_ITEM(file, export, gtkExport, fmenu, group); IMAGE_ITEM(file, export, gtkExport, fmenu, group);
ADD_SEP(file, fmenu); ADD_SEP(file, fmenu);
IMAGE_ITEM(file, printpreview, gtkPrintPreview, fmenu, group); IMAGE_ITEM(file, printpreview, gtkPrintPreview, fmenu, group);

View File

@ -15,24 +15,26 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _NETSURF_GTK_MENU_H_ #ifndef NETSURF_GTK_MENU_H_
#define _NETSURF_GTK_MENU_H_ #define NETSURF_GTK_MENU_H_
#include <gtk/gtk.h> #include <gtk/gtk.h>
/**
* File menu item on menubar
*/
struct nsgtk_file_menu { struct nsgtk_file_menu {
GtkMenuItem *file; /* File menu item on menubar */ GtkMenuItem *file;
GtkMenu *file_menu; GtkMenu *file_menu;
GtkWidget *newwindow_menuitem; GtkWidget *newwindow_menuitem;
GtkWidget *newtab_menuitem; GtkWidget *newtab_menuitem;
GtkWidget *openfile_menuitem; GtkWidget *openfile_menuitem;
GtkWidget *closewindow_menuitem; GtkWidget *closewindow_menuitem;
GtkWidget *savepage_menuitem; GtkWidget *export_menuitem;
GtkWidget *export_menuitem; struct nsgtk_export_submenu *export_submenu;
struct nsgtk_export_submenu *export_submenu; GtkWidget *printpreview_menuitem;
GtkWidget *printpreview_menuitem; GtkWidget *print_menuitem;
GtkWidget *print_menuitem; GtkWidget *quit_menuitem;
GtkWidget *quit_menuitem;
}; };
struct nsgtk_edit_menu { struct nsgtk_edit_menu {
@ -88,35 +90,34 @@ struct nsgtk_tools_menu {
}; };
struct nsgtk_help_menu { struct nsgtk_help_menu {
GtkMenuItem *help; /* Help menu item on menubar */ GtkMenuItem *help; /* Help menu item on menubar */
GtkMenu *help_menu; GtkMenu *help_menu;
GtkWidget *contents_menuitem; GtkWidget *contents_menuitem;
GtkWidget *guide_menuitem; GtkWidget *guide_menuitem;
GtkWidget *info_menuitem; GtkWidget *info_menuitem;
GtkWidget *about_menuitem; GtkWidget *about_menuitem;
}; };
struct nsgtk_export_submenu { struct nsgtk_export_submenu {
GtkMenu *export_menu; GtkMenu *export_menu;
GtkWidget *plaintext_menuitem; GtkWidget *savepage_menuitem;
GtkWidget *drawfile_menuitem; GtkWidget *plaintext_menuitem;
GtkWidget *postscript_menuitem; GtkWidget *pdf_menuitem;
GtkWidget *pdf_menuitem;
}; };
struct nsgtk_scaleview_submenu { struct nsgtk_scaleview_submenu {
GtkMenu *scaleview_menu; GtkMenu *scaleview_menu;
GtkWidget *zoomplus_menuitem; GtkWidget *zoomplus_menuitem;
GtkWidget *zoomminus_menuitem; GtkWidget *zoomminus_menuitem;
GtkWidget *zoomnormal_menuitem; GtkWidget *zoomnormal_menuitem;
}; };
struct nsgtk_tabs_submenu { struct nsgtk_tabs_submenu {
GtkMenu *tabs_menu; GtkMenu *tabs_menu;
GtkWidget *nexttab_menuitem; GtkWidget *nexttab_menuitem;
GtkWidget *prevtab_menuitem; GtkWidget *prevtab_menuitem;
GtkWidget *closetab_menuitem; GtkWidget *closetab_menuitem;
}; };
struct nsgtk_images_submenu { struct nsgtk_images_submenu {

View File

@ -624,7 +624,7 @@ nsgtk_on_newtab_activate_menu(GtkMenuItem *widget, gpointer data)
} }
/** /**
* menu signal handler for activation on openfile item * menu signal handler for activation on open file item
*/ */
static gboolean static gboolean
nsgtk_on_openfile_activate_menu(GtkMenuItem *widget, gpointer data) nsgtk_on_openfile_activate_menu(GtkMenuItem *widget, gpointer data)
@ -636,303 +636,60 @@ nsgtk_on_openfile_activate_menu(GtkMenuItem *widget, gpointer data)
/** /**
* callback to determine if a path is a directory. * menu signal handler for activation on export complete page item
*
* \param info The path information
* \param data context pointer set to NULL
* \return TRUE if path is a directory else false
*/ */
static gboolean static gboolean
nsgtk_filter_directory(const GtkFileFilterInfo *info, nsgtk_on_savepage_activate_menu(GtkMenuItem *widget, gpointer data)
gpointer data)
{ {
DIR *d = opendir(info->filename); struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
if (d == NULL) nsgtk_window_item_activate(g->top_level, SAVEPAGE_BUTTON);
return FALSE;
closedir(d);
return TRUE;
}
MULTIHANDLER(savepage)
{
if (!browser_window_has_content(nsgtk_get_browser_window(g->top_level)))
return FALSE;
GtkWidget *fc;
DIR *d;
char *path;
nserror res;
GtkFileFilter *filter;
fc = gtk_file_chooser_dialog_new(
messages_get("gtkcompleteSave"), g->window,
GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
filter = gtk_file_filter_new();
gtk_file_filter_set_name(filter, "Directories");
gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
nsgtk_filter_directory, NULL, NULL);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter);
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fc), filter);
res = nsurl_nice(browser_window_access_url(
nsgtk_get_browser_window(g->top_level)), &path, false);
if (res != NSERROR_OK) {
path = strdup(messages_get("SaveText"));
if (path == NULL) {
nsgtk_warning("NoMemory", 0);
return FALSE;
}
}
if (access(path, F_OK) != 0)
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), path);
free(path);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc),
TRUE);
if (gtk_dialog_run(GTK_DIALOG(fc)) != GTK_RESPONSE_ACCEPT) {
gtk_widget_destroy(fc);
return TRUE;
}
path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
d = opendir(path);
if (d == NULL) {
NSLOG(netsurf, INFO,
"Unable to open directory %s for complete save: %s",
path,
strerror(errno));
if (errno == ENOTDIR)
nsgtk_warning("NoDirError", path);
else
nsgtk_warning("gtkFileError", path);
gtk_widget_destroy(fc);
g_free(path);
return TRUE;
}
closedir(d);
save_complete(browser_window_get_content(nsgtk_get_browser_window(
g->top_level)), path, NULL);
g_free(path);
gtk_widget_destroy(fc);
return TRUE; return TRUE;
} }
MULTIHANDLER(pdf) /**
* menu signal handler for activation on export pdf item
*/
static gboolean
nsgtk_on_pdf_activate_menu(GtkMenuItem *widget, gpointer data)
{ {
#ifdef WITH_PDF_EXPORT struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
nsgtk_window_item_activate(g->top_level, PDF_BUTTON);
GtkWidget *save_dialog;
struct browser_window *bw = nsgtk_get_browser_window(g->top_level);
struct print_settings *settings;
char filename[PATH_MAX];
char dirname[PATH_MAX];
char *url_name;
nserror res;
NSLOG(netsurf, INFO, "Print preview (generating PDF) started.");
res = nsurl_nice(browser_window_access_url(bw), &url_name, true);
if (res != NSERROR_OK) {
nsgtk_warning(messages_get_errorcode(res), 0);
return TRUE;
}
strncpy(filename, url_name, PATH_MAX);
strncat(filename, ".pdf", PATH_MAX - strlen(filename));
filename[PATH_MAX - 1] = '\0';
free(url_name);
strncpy(dirname, option_downloads_directory, PATH_MAX);
strncat(dirname, "/", PATH_MAX - strlen(dirname));
dirname[PATH_MAX - 1] = '\0';
/* this way the scale used by PDF functions is synchronised with that
* used by the all-purpose print interface
*/
haru_nsfont_set_scale((float)option_export_scale / 100);
save_dialog = gtk_file_chooser_dialog_new("Export to PDF", g->window,
GTK_FILE_CHOOSER_ACTION_SAVE,
NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
dirname);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
filename);
if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) {
gchar *filename = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(save_dialog));
settings = print_make_settings(PRINT_OPTIONS,
(const char *) filename, &haru_nsfont);
g_free(filename);
if (settings == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
gtk_widget_destroy(save_dialog);
return TRUE;
}
/* This will clean up the print_settings object for us */
print_basic_run(browser_window_get_content(bw),
&pdf_printer, settings);
}
gtk_widget_destroy(save_dialog);
#endif /* WITH_PDF_EXPORT */
return TRUE; return TRUE;
} }
MULTIHANDLER(plaintext) /**
{ * menu signal handler for activation on export plain text item
if (!browser_window_has_content(nsgtk_get_browser_window(g->top_level))) */
return FALSE; static gboolean
nsgtk_on_plaintext_activate_menu(GtkMenuItem *widget, gpointer data)
GtkWidget *fc = gtk_file_chooser_dialog_new(
messages_get("gtkplainSave"), g->window,
GTK_FILE_CHOOSER_ACTION_SAVE,
NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
char *filename;
nserror res;
res = nsurl_nice(browser_window_access_url(
nsgtk_get_browser_window(g->top_level)),
&filename, false);
if (res != NSERROR_OK) {
filename = strdup(messages_get("SaveText"));
if (filename == NULL) {
nsgtk_warning("NoMemory", 0);
return FALSE;
}
}
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), filename);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc),
TRUE);
free(filename);
if (gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_ACCEPT) {
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
save_as_text(browser_window_get_content(
nsgtk_get_browser_window(
g->top_level)), filename);
g_free(filename);
}
gtk_widget_destroy(fc);
return TRUE;
}
MULTIHANDLER(drawfile)
{
return TRUE;
}
MULTIHANDLER(postscript)
{
return TRUE;
}
MULTIHANDLER(printpreview)
{ {
struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
nsgtk_window_item_activate(g->top_level, PLAINTEXT_BUTTON);
return TRUE; return TRUE;
} }
MULTIHANDLER(print) /**
* menu signal handler for activation on print preview item
*/
static gboolean
nsgtk_on_printpreview_activate_menu(GtkMenuItem *widget, gpointer data)
{ {
struct browser_window *bw = nsgtk_get_browser_window(g->top_level); struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
nsgtk_window_item_activate(g->top_level, PRINTPREVIEW_BUTTON);
return TRUE;
}
GtkPrintOperation *print_op;
GtkPageSetup *page_setup;
GtkPrintSettings *print_settings;
GtkPrintOperationResult res = GTK_PRINT_OPERATION_RESULT_ERROR;
struct print_settings *nssettings;
char *settings_fname = NULL;
print_op = gtk_print_operation_new();
if (print_op == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
return TRUE;
}
/* use previously saved settings if any */
netsurf_mkpath(&settings_fname, NULL, 2, nsgtk_config_home, "Print");
if (settings_fname != NULL) {
print_settings = gtk_print_settings_new_from_file(settings_fname, NULL);
if (print_settings != NULL) {
gtk_print_operation_set_print_settings(print_op,
print_settings);
/* We're not interested in the settings any more */
g_object_unref(print_settings);
}
}
content_to_print = browser_window_get_content(bw);
page_setup = gtk_print_run_page_setup_dialog(g->window, NULL, NULL);
if (page_setup == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
free(settings_fname);
g_object_unref(print_op);
return TRUE;
}
gtk_print_operation_set_default_page_setup(print_op, page_setup);
nssettings = print_make_settings(PRINT_DEFAULT, NULL, nsgtk_layout_table);
g_signal_connect(print_op, "begin_print",
G_CALLBACK(gtk_print_signal_begin_print), nssettings);
g_signal_connect(print_op, "draw_page",
G_CALLBACK(gtk_print_signal_draw_page), NULL);
g_signal_connect(print_op, "end_print",
G_CALLBACK(gtk_print_signal_end_print), nssettings);
if (content_get_type(browser_window_get_content(bw)) !=
CONTENT_TEXTPLAIN) {
res = gtk_print_operation_run(print_op,
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
g->window,
NULL);
}
/* if the settings were used save them for future use */
if (settings_fname != NULL) {
if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
/* Do not increment the settings reference */
print_settings =
gtk_print_operation_get_print_settings(print_op);
gtk_print_settings_to_file(print_settings,
settings_fname,
NULL);
}
free(settings_fname);
}
/* Our print_settings object is destroyed by the end print handler */
g_object_unref(page_setup);
g_object_unref(print_op);
/**
* menu signal handler for activation on print item
*/
static gboolean
nsgtk_on_print_activate_menu(GtkMenuItem *widget, gpointer data)
{
struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
nsgtk_window_item_activate(g->top_level, PRINT_BUTTON);
return TRUE; return TRUE;
} }
@ -1839,16 +1596,20 @@ static nserror nsgtk_menu_initialise(struct nsgtk_scaffolding *g)
#define ITEM_POP(p, q) \ #define ITEM_POP(p, q) \
g->menus[p##_BUTTON].popup = g->menu_popup->q##_menuitem g->menus[p##_BUTTON].popup = g->menu_popup->q##_menuitem
/* file menu */
ITEM_MAIN(NEWWINDOW, file_submenu, newwindow); ITEM_MAIN(NEWWINDOW, file_submenu, newwindow);
ITEM_MAIN(NEWTAB, file_submenu, newtab); ITEM_MAIN(NEWTAB, file_submenu, newtab);
ITEM_MAIN(OPENFILE, file_submenu, openfile); ITEM_MAIN(OPENFILE, file_submenu, openfile);
ITEM_MAIN(PRINT, file_submenu, print);
ITEM_MAIN(CLOSEWINDOW, file_submenu, closewindow); ITEM_MAIN(CLOSEWINDOW, file_submenu, closewindow);
ITEM_MAIN(SAVEPAGE, file_submenu, savepage);
ITEM_MAIN(PRINTPREVIEW, file_submenu, printpreview); ITEM_MAIN(PRINTPREVIEW, file_submenu, printpreview);
ITEM_MAIN(PRINT, file_submenu, print); ITEM_MAIN(PRINT, file_submenu, print);
ITEM_MAIN(QUIT, file_submenu, quit); ITEM_MAIN(QUIT, file_submenu, quit);
/* file - export submenu */
ITEM_SUB(SAVEPAGE, file_submenu, export, savepage);
ITEM_SUB(PLAINTEXT, file_submenu, export, plaintext);
ITEM_SUB(PDF, file_submenu, export, pdf);
/* edit menu */
ITEM_MAIN(CUT, edit_submenu, cut); ITEM_MAIN(CUT, edit_submenu, cut);
ITEM_MAIN(COPY, edit_submenu, copy); ITEM_MAIN(COPY, edit_submenu, copy);
ITEM_MAIN(PASTE, edit_submenu, paste); ITEM_MAIN(PASTE, edit_submenu, paste);
@ -1856,45 +1617,52 @@ static nserror nsgtk_menu_initialise(struct nsgtk_scaffolding *g)
ITEM_MAIN(SELECTALL, edit_submenu, selectall); ITEM_MAIN(SELECTALL, edit_submenu, selectall);
ITEM_MAIN(FIND, edit_submenu, find); ITEM_MAIN(FIND, edit_submenu, find);
ITEM_MAIN(PREFERENCES, edit_submenu, preferences); ITEM_MAIN(PREFERENCES, edit_submenu, preferences);
/* view menu */
ITEM_MAIN(STOP, view_submenu, stop); ITEM_MAIN(STOP, view_submenu, stop);
ITEM_POP(STOP, stop);
ITEM_MAIN(RELOAD, view_submenu, reload); ITEM_MAIN(RELOAD, view_submenu, reload);
ITEM_POP(RELOAD, reload);
ITEM_MAIN(FULLSCREEN, view_submenu, fullscreen); ITEM_MAIN(FULLSCREEN, view_submenu, fullscreen);
ITEM_MAIN(DOWNLOADS, tools_submenu, downloads);
ITEM_MAIN(SAVEWINDOWSIZE, view_submenu, savewindowsize); ITEM_MAIN(SAVEWINDOWSIZE, view_submenu, savewindowsize);
/* view - scale submenu */
ITEM_SUB(ZOOMPLUS, view_submenu, scaleview, zoomplus);
ITEM_SUB(ZOOMMINUS, view_submenu, scaleview, zoomminus);
ITEM_SUB(ZOOMNORMAL, view_submenu, scaleview, zoomnormal);
/* view - tabs submenu */
ITEM_SUB(NEXTTAB, view_submenu, tabs, nexttab);
ITEM_SUB(PREVTAB, view_submenu, tabs, prevtab);
ITEM_SUB(CLOSETAB, view_submenu, tabs, closetab);
/* navigation menu */
ITEM_MAIN(BACK, nav_submenu, back); ITEM_MAIN(BACK, nav_submenu, back);
ITEM_POP(BACK, back);
ITEM_MAIN(FORWARD, nav_submenu, forward); ITEM_MAIN(FORWARD, nav_submenu, forward);
ITEM_POP(FORWARD, forward);
ITEM_MAIN(HOME, nav_submenu, home); ITEM_MAIN(HOME, nav_submenu, home);
ITEM_MAIN(LOCALHISTORY, nav_submenu, localhistory); ITEM_MAIN(LOCALHISTORY, nav_submenu, localhistory);
ITEM_MAIN(GLOBALHISTORY, nav_submenu, globalhistory); ITEM_MAIN(GLOBALHISTORY, nav_submenu, globalhistory);
ITEM_MAIN(ADDBOOKMARKS, nav_submenu, addbookmarks); ITEM_MAIN(ADDBOOKMARKS, nav_submenu, addbookmarks);
ITEM_MAIN(SHOWBOOKMARKS, nav_submenu, showbookmarks); ITEM_MAIN(SHOWBOOKMARKS, nav_submenu, showbookmarks);
ITEM_MAIN(SHOWCOOKIES, tools_submenu, showcookies);
ITEM_MAIN(OPENLOCATION, nav_submenu, openlocation); ITEM_MAIN(OPENLOCATION, nav_submenu, openlocation);
ITEM_MAIN(CONTENTS, help_submenu, contents);
ITEM_MAIN(INFO, help_submenu, info);
ITEM_MAIN(GUIDE, help_submenu, guide);
ITEM_MAIN(ABOUT, help_submenu, about);
ITEM_SUB(PLAINTEXT, file_submenu, export, plaintext);
ITEM_SUB(PDF, file_submenu, export, pdf);
ITEM_SUB(DRAWFILE, file_submenu, export, drawfile);
ITEM_SUB(POSTSCRIPT, file_submenu, export, postscript);
ITEM_SUB(ZOOMPLUS, view_submenu, scaleview, zoomplus);
ITEM_SUB(ZOOMMINUS, view_submenu, scaleview, zoomminus);
ITEM_SUB(ZOOMNORMAL, view_submenu, scaleview, zoomnormal);
ITEM_SUB(NEXTTAB, view_submenu, tabs, nexttab);
ITEM_SUB(PREVTAB, view_submenu, tabs, prevtab);
ITEM_SUB(CLOSETAB, view_submenu, tabs, closetab);
/* development submenu */ /* tools menu */
ITEM_MAIN(DOWNLOADS, tools_submenu, downloads);
ITEM_MAIN(SHOWCOOKIES, tools_submenu, showcookies);
/* tools > developer submenu */
ITEM_SUB(VIEWSOURCE, tools_submenu, developer, viewsource); ITEM_SUB(VIEWSOURCE, tools_submenu, developer, viewsource);
ITEM_SUB(TOGGLEDEBUGGING, tools_submenu, developer, toggledebugging); ITEM_SUB(TOGGLEDEBUGGING, tools_submenu, developer, toggledebugging);
ITEM_SUB(SAVEBOXTREE, tools_submenu, developer, debugboxtree); ITEM_SUB(SAVEBOXTREE, tools_submenu, developer, debugboxtree);
ITEM_SUB(SAVEDOMTREE, tools_submenu, developer, debugdomtree); ITEM_SUB(SAVEDOMTREE, tools_submenu, developer, debugdomtree);
/* help menu */
ITEM_MAIN(CONTENTS, help_submenu, contents);
ITEM_MAIN(GUIDE, help_submenu, guide);
ITEM_MAIN(INFO, help_submenu, info);
ITEM_MAIN(ABOUT, help_submenu, about);
/* popup menu */
ITEM_POP(STOP, stop);
ITEM_POP(RELOAD, reload);
ITEM_POP(BACK, back);
ITEM_POP(FORWARD, forward);
#undef ITEM_MAIN #undef ITEM_MAIN
#undef ITEM_SUB #undef ITEM_SUB

View File

@ -24,18 +24,23 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "netsurf/browser_window.h"
#include "desktop/browser_history.h"
#include "desktop/searchweb.h"
#include "desktop/search.h"
#include "utils/log.h" #include "utils/log.h"
#include "utils/messages.h" #include "utils/messages.h"
#include "utils/nsoption.h" #include "utils/nsoption.h"
#include "utils/file.h" #include "utils/file.h"
#include "utils/nsurl.h" #include "utils/nsurl.h"
#include "utils/corestrings.h" #include "utils/corestrings.h"
#include "desktop/browser_history.h"
#include "desktop/searchweb.h"
#include "desktop/search.h"
#include "desktop/save_complete.h"
#include "desktop/save_text.h"
#include "desktop/print.h"
#include "netsurf/content.h"
#include "netsurf/browser_window.h"
#include "gtk/toolbar_items.h" #include "gtk/toolbar_items.h"
#include "gtk/completion.h" #include "gtk/completion.h"
@ -49,6 +54,9 @@
#include "gtk/resources.h" #include "gtk/resources.h"
#include "gtk/schedule.h" #include "gtk/schedule.h"
#include "gtk/local_history.h" #include "gtk/local_history.h"
#include "gtk/tabs.h"
#include "gtk/print.h"
#include "gtk/layout_pango.h"
#include "gtk/toolbar.h" #include "gtk/toolbar.h"
/** /**
@ -2193,7 +2201,7 @@ closetab_button_clicked_cb(GtkWidget *widget, gpointer data)
{ {
struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data; struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
nsgtk_tab_close_current(tb->widget); nsgtk_tab_close_current(GTK_NOTEBOOK(tb->widget));
return TRUE; return TRUE;
} }
@ -2216,8 +2224,71 @@ closewindow_button_clicked_cb(GtkWidget *widget, gpointer data)
} }
static nserror
nsgtk_saveas_dialog(struct browser_window *bw,
const char *title,
GtkWindow *parent,
bool folder,
gchar **path_out)
{
nserror res;
GtkWidget *fc; /* file chooser widget */
GtkFileChooserAction action;
char *path; /* proposed path */
if (!browser_window_has_content(bw)) {
/* cannot save a page with no content */
return NSERROR_INVALID;
}
if (folder) {
action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
} else {
action = GTK_FILE_CHOOSER_ACTION_SAVE;
}
fc = gtk_file_chooser_dialog_new(title,
parent,
action,
NSGTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
NSGTK_STOCK_SAVE,
GTK_RESPONSE_ACCEPT,
NULL);
/* set a default file name */
res = nsurl_nice(browser_window_access_url(bw), &path, false);
if (res != NSERROR_OK) {
path = strdup(messages_get("SaveText"));
if (path == NULL) {
gtk_widget_destroy(fc);
return NSERROR_NOMEM;
}
}
if ((!folder) || (access(path, F_OK) != 0)) {
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), path);
}
free(path);
/* confirm overwriting */
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), TRUE);
/* run the dialog to let user select path */
if (gtk_dialog_run(GTK_DIALOG(fc)) != GTK_RESPONSE_ACCEPT) {
gtk_widget_destroy(fc);
return NSERROR_NOT_FOUND;
}
*path_out = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
gtk_widget_destroy(fc);
return NSERROR_OK;
}
/** /**
* handler for new window tool bar item clicked signal * handler for full save export tool bar item clicked signal
* *
* \param widget The widget the signal is being delivered to. * \param widget The widget the signal is being delivered to.
* \param data The toolbar context passed when the signal was connected * \param data The toolbar context passed when the signal was connected
@ -2226,6 +2297,235 @@ closewindow_button_clicked_cb(GtkWidget *widget, gpointer data)
static gboolean static gboolean
savepage_button_clicked_cb(GtkWidget *widget, gpointer data) savepage_button_clicked_cb(GtkWidget *widget, gpointer data)
{ {
struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
struct browser_window *bw;
DIR *d;
gchar *path;
nserror res;
GtkWidget *toplevel;
bw = tb->get_bw(tb->get_bw_ctx);
toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
res = nsgtk_saveas_dialog(bw,
messages_get("gtkcompleteSave"),
GTK_WINDOW(toplevel),
true,
&path);
if (res != NSERROR_OK) {
return FALSE;
}
d = opendir(path);
if (d == NULL) {
NSLOG(netsurf, INFO,
"Unable to open directory %s for complete save: %s",
path,
strerror(errno));
if (errno == ENOTDIR) {
nsgtk_warning("NoDirError", path);
} else {
nsgtk_warning("gtkFileError", path);
}
g_free(path);
return TRUE;
}
closedir(d);
save_complete(browser_window_get_content(bw), path, NULL);
g_free(path);
return TRUE;
}
/**
* handler for pdf export tool bar item clicked signal
*
* \param widget The widget the signal is being delivered to.
* \param data The toolbar context passed when the signal was connected
* \return TRUE
*/
static gboolean
pdf_button_clicked_cb(GtkWidget *widget, gpointer data)
{
struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
struct browser_window *bw;
GtkWidget *toplevel;
gchar *filename;
nserror res;
bw = tb->get_bw(tb->get_bw_ctx);
toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
res = nsgtk_saveas_dialog(bw,
"Export to PDF",
GTK_WINDOW(toplevel),
false,
&filename);
if (res != NSERROR_OK) {
return FALSE;
}
#ifdef WITH_PDF_EXPORT
struct print_settings *settings;
/* this way the scale used by PDF functions is synchronised with that
* used by the all-purpose print interface
*/
haru_nsfont_set_scale((float)option_export_scale / 100);
settings = print_make_settings(PRINT_OPTIONS,
(const char *) filename,
&haru_nsfont);
g_free(filename);
if (settings == NULL) {
return TRUE;
}
/* This will clean up the print_settings object for us */
print_basic_run(browser_window_get_content(bw), &pdf_printer, settings);
#endif
return TRUE;
}
/**
* handler for plain text export tool bar item clicked signal
*
* \param widget The widget the signal is being delivered to.
* \param data The toolbar context passed when the signal was connected
* \return TRUE
*/
static gboolean
plaintext_button_clicked_cb(GtkWidget *widget, gpointer data)
{
struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
struct browser_window *bw;
GtkWidget *toplevel;
gchar *filename;
nserror res;
bw = tb->get_bw(tb->get_bw_ctx);
toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
res = nsgtk_saveas_dialog(bw,
messages_get("gtkplainSave"),
GTK_WINDOW(toplevel),
false,
&filename);
if (res != NSERROR_OK) {
return FALSE;
}
save_as_text(browser_window_get_content(bw), filename);
g_free(filename);
return TRUE;
}
/**
* handler for print tool bar item clicked signal
*
* \param widget The widget the signal is being delivered to.
* \param data The toolbar context passed when the signal was connected
* \return TRUE
*/
static gboolean
print_button_clicked_cb(GtkWidget *widget, gpointer data)
{
struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data;
struct browser_window *bw;
GtkPrintOperation *print_op;
GtkPageSetup *page_setup;
GtkPrintSettings *print_settings;
GtkPrintOperationResult res = GTK_PRINT_OPERATION_RESULT_ERROR;
struct print_settings *nssettings;
char *settings_fname = NULL;
GtkWidget *toplevel;
bw = tb->get_bw(tb->get_bw_ctx);
toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
print_op = gtk_print_operation_new();
if (print_op == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
return TRUE;
}
/* use previously saved settings if any */
netsurf_mkpath(&settings_fname, NULL, 2, nsgtk_config_home, "Print");
if (settings_fname != NULL) {
print_settings = gtk_print_settings_new_from_file(settings_fname, NULL);
if (print_settings != NULL) {
gtk_print_operation_set_print_settings(print_op,
print_settings);
/* We're not interested in the settings any more */
g_object_unref(print_settings);
}
}
content_to_print = browser_window_get_content(bw);
page_setup = gtk_print_run_page_setup_dialog(GTK_WINDOW(toplevel),
NULL,
NULL);
if (page_setup == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
free(settings_fname);
g_object_unref(print_op);
return TRUE;
}
gtk_print_operation_set_default_page_setup(print_op, page_setup);
nssettings = print_make_settings(PRINT_DEFAULT,
NULL,
nsgtk_layout_table);
g_signal_connect(print_op,
"begin_print",
G_CALLBACK(gtk_print_signal_begin_print),
nssettings);
g_signal_connect(print_op,
"draw_page",
G_CALLBACK(gtk_print_signal_draw_page),
NULL);
g_signal_connect(print_op,
"end_print",
G_CALLBACK(gtk_print_signal_end_print),
nssettings);
if (content_get_type(browser_window_get_content(bw)) != CONTENT_TEXTPLAIN) {
res = gtk_print_operation_run(print_op,
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
GTK_WINDOW(toplevel),
NULL);
}
/* if the settings were used save them for future use */
if (settings_fname != NULL) {
if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
/* Do not increment the settings reference */
print_settings = gtk_print_operation_get_print_settings(print_op);
gtk_print_settings_to_file(print_settings,
settings_fname,
NULL);
}
free(settings_fname);
}
/* Our print_settings object is destroyed by the end print handler */
g_object_unref(page_setup);
g_object_unref(print_op);
return TRUE;
} }
@ -2628,7 +2928,7 @@ nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb,
if (tb->buttons[itemid]->button != NULL) { if (tb->buttons[itemid]->button != NULL) {
widget = GTK_WIDGET(tb->buttons[itemid]->button); widget = GTK_WIDGET(tb->buttons[itemid]->button);
} else { } else {
widget = tb->widget; widget = GTK_WIDGET(tb->widget);
} }
tb->buttons[itemid]->bhandler(widget, tb); tb->buttons[itemid]->bhandler(widget, tb);

View File

@ -103,12 +103,12 @@ TOOLBAR_ITEM(OPENFILE_BUTTON, openfile, true, openfile_button_clicked_cb)
TOOLBAR_ITEM(CLOSETAB_BUTTON, closetab, false, closetab_button_clicked_cb) TOOLBAR_ITEM(CLOSETAB_BUTTON, closetab, false, closetab_button_clicked_cb)
TOOLBAR_ITEM(CLOSEWINDOW_BUTTON, closewindow, true, closewindow_button_clicked_cb) TOOLBAR_ITEM(CLOSEWINDOW_BUTTON, closewindow, true, closewindow_button_clicked_cb)
TOOLBAR_ITEM(SAVEPAGE_BUTTON, savepage, true, savepage_button_clicked_cb) TOOLBAR_ITEM(SAVEPAGE_BUTTON, savepage, true, savepage_button_clicked_cb)
TOOLBAR_ITEM(PDF_BUTTON, pdf, false, NULL) TOOLBAR_ITEM(PDF_BUTTON, pdf, false, pdf_button_clicked_cb)
TOOLBAR_ITEM(PLAINTEXT_BUTTON, plaintext, true, NULL) TOOLBAR_ITEM(PLAINTEXT_BUTTON, plaintext, true, plaintext_button_clicked_cb)
TOOLBAR_ITEM(DRAWFILE_BUTTON, drawfile, false, NULL) TOOLBAR_ITEM(DRAWFILE_BUTTON, drawfile, false, NULL)
TOOLBAR_ITEM(POSTSCRIPT_BUTTON, postscript, false, NULL) TOOLBAR_ITEM(POSTSCRIPT_BUTTON, postscript, false, NULL)
TOOLBAR_ITEM(PRINTPREVIEW_BUTTON, printpreview, false, NULL) TOOLBAR_ITEM(PRINTPREVIEW_BUTTON, printpreview, false, NULL)
TOOLBAR_ITEM(PRINT_BUTTON, print, true, NULL) TOOLBAR_ITEM(PRINT_BUTTON, print, true, print_button_clicked_cb)
TOOLBAR_ITEM(QUIT_BUTTON, quit, true, NULL) TOOLBAR_ITEM(QUIT_BUTTON, quit, true, NULL)
TOOLBAR_ITEM(CUT_BUTTON, cut, true, NULL) TOOLBAR_ITEM(CUT_BUTTON, cut, true, NULL)
TOOLBAR_ITEM(COPY_BUTTON, copy, true, NULL) TOOLBAR_ITEM(COPY_BUTTON, copy, true, NULL)

View File

@ -2872,11 +2872,11 @@ de.gtk.gtkplainSave:Als Text speichern
fr.gtk.gtkplainSave:Enregistrer sans mise en forme fr.gtk.gtkplainSave:Enregistrer sans mise en forme
it.gtk.gtkplainSave:Salva come testo it.gtk.gtkplainSave:Salva come testo
nl.gtk.gtkplainSave:Als tekst bewaren nl.gtk.gtkplainSave:Als tekst bewaren
en.gtk.gtkcompleteSave:Save webpage complete - select an empty directory en.gtk.gtkcompleteSave:Export complete page as a folder
de.gtk.gtkcompleteSave:Seite komplett speichern - ein leeres Verzeichnis wählen de.gtk.gtkcompleteSave:Seite komplett speichern
fr.gtk.gtkcompleteSave:Enregistrer page web complète - sélectioner un dossier vide fr.gtk.gtkcompleteSave:Enregistrer page web complète
it.gtk.gtkcompleteSave:Salva l'intera pagina web - seleziona una directory vuota it.gtk.gtkcompleteSave:Salva l'intera pagina web
nl.gtk.gtkcompleteSave:Complete webpagina bewaren - selecteer een lege map nl.gtk.gtkcompleteSave:Complete webpagina bewaren
en.gtk.gtkSaveConfirm:File saved en.gtk.gtkSaveConfirm:File saved
de.gtk.gtkSaveConfirm:Datei gespeichert de.gtk.gtkSaveConfirm:Datei gespeichert
fr.gtk.gtkSaveConfirm:Fichier enregistré fr.gtk.gtkSaveConfirm:Fichier enregistré
@ -2957,16 +2957,16 @@ de.gtk.gtkCloseWindow:Fenster schließen
fr.gtk.gtkCloseWindow:_Fermer la fenêtre fr.gtk.gtkCloseWindow:_Fermer la fenêtre
it.gtk.gtkCloseWindow:_Chiudi finestra it.gtk.gtkCloseWindow:_Chiudi finestra
nl.gtk.gtkCloseWindow:_Venster sluiten nl.gtk.gtkCloseWindow:_Venster sluiten
en.gtk.gtkSavePage:Save Page…
de.gtk.gtkSavePage:Seite speichern..
fr.gtk.gtkSavePage:Enregistrer la Page...
it.gtk.gtkSavePage:Salva pagina...
nl.gtk.gtkSavePage:Pagina bewaren...
en.gtk.gtkExport:Export en.gtk.gtkExport:Export
de.gtk.gtkExport:Exportieren de.gtk.gtkExport:Exportieren
fr.gtk.gtkExport:Exporter fr.gtk.gtkExport:Exporter
it.gtk.gtkExport:Esporta it.gtk.gtkExport:Esporta
nl.gtk.gtkExport:Exporteren nl.gtk.gtkExport:Exporteren
en.gtk.gtkSavePage:Complete Page…
de.gtk.gtkSavePage:Seite speichern..
fr.gtk.gtkSavePage:Enregistrer la Page...
it.gtk.gtkSavePage:Salva pagina...
nl.gtk.gtkSavePage:Pagina bewaren...
en.gtk.gtkPlainText:Plain Text… en.gtk.gtkPlainText:Plain Text…
de.gtk.gtkPlainText:Reiner Text.. de.gtk.gtkPlainText:Reiner Text..
fr.gtk.gtkPlainText:Texte... fr.gtk.gtkPlainText:Texte...