diff options
author | Marco Pesenti Gritti <marco@it.gnome.org> | 2002-12-31 21:52:44 +0800 |
---|---|---|
committer | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2002-12-31 21:52:44 +0800 |
commit | 6afec98b2cc4c33cd4128d045035a0ec7d43629c (patch) | |
tree | fbca72a16cc232b59b16adbe365f29f8bba1b010 | |
parent | beec33b028bdeb5f0da6ed51305f32e3b8041f6e (diff) | |
download | gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar.gz gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar.bz2 gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar.lz gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar.xz gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.tar.zst gsoc2013-epiphany-6afec98b2cc4c33cd4128d045035a0ec7d43629c.zip |
Resync with galeon.
2002-12-31 Marco Pesenti Gritti <marco@it.gnome.org>
* embed/mozilla/FilePicker.cpp:
* embed/mozilla/FilePicker.h:
* embed/mozilla/mozilla-embed-shell.cpp:
Resync with galeon.
* data/epiphany.schemas.in:
* lib/ephy-bonobo-extensions.c: (ephy_bonobo_add_numbered_widget):
* lib/ephy-bonobo-extensions.h:
* lib/toolbar/Makefile.am:
* lib/toolbar/ephy-tbi-std-toolitem.c:
(ephy_tbi_std_toolitem_init),
(ephy_tbi_std_toolitem_get_icon_impl),
(ephy_tbi_std_toolitem_get_name_human_impl),
(ephy_tbi_std_toolitem_to_string_impl),
(ephy_tbi_std_toolitem_add_to_bonobo_tb_impl),
(ephy_tbi_std_toolitem_parse_properties_impl),
(ephy_tbi_std_toolitem_set_item):
* lib/toolbar/ephy-tbi-std-toolitem.h:
* lib/toolbar/ephy-toolbar-item-factory.c:
(ephy_tb_item_factory_init),
(ephy_toolbar_item_create_from_string),
(ephy_toolbar_item_register_type):
* lib/toolbar/ephy-toolbar-item-factory.h:
* src/Makefile.am:
* src/toolbar.c: (toolbar_class_init), (toolbar_set_property),
(toolbar_get_widgets), (toolbar_init), (toolbar_finalize),
(toolbar_navigation_button_set_sensitive),
(toolbar_button_set_sensitive):
* src/window-commands.c:
Resync with galeon. Now we use a widget for navigation
buttons.
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | data/epiphany.schemas.in | 2 | ||||
-rw-r--r-- | embed/mozilla/FilePicker.cpp | 67 | ||||
-rw-r--r-- | embed/mozilla/FilePicker.h | 17 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed-shell.cpp | 8 | ||||
-rw-r--r-- | lib/ephy-bonobo-extensions.c | 16 | ||||
-rw-r--r-- | lib/ephy-bonobo-extensions.h | 2 | ||||
-rw-r--r-- | lib/toolbar/Makefile.am | 4 | ||||
-rw-r--r-- | lib/toolbar/ephy-tb-button.c | 746 | ||||
-rw-r--r-- | lib/toolbar/ephy-tb-button.h | 79 | ||||
-rw-r--r-- | lib/toolbar/ephy-tbi-std-toolitem.c | 112 | ||||
-rw-r--r-- | lib/toolbar/ephy-tbi-std-toolitem.h | 6 | ||||
-rw-r--r-- | lib/toolbar/ephy-toolbar-item-factory.c | 80 | ||||
-rw-r--r-- | lib/toolbar/ephy-toolbar-item-factory.h | 4 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/ephy-navigation-button.c | 614 | ||||
-rw-r--r-- | src/ephy-navigation-button.h | 79 | ||||
-rw-r--r-- | src/ephy-tbi.c | 193 | ||||
-rw-r--r-- | src/ephy-tbi.h | 70 | ||||
-rwxr-xr-x | src/toolbar.c | 393 | ||||
-rw-r--r-- | src/window-commands.c | 15 |
21 files changed, 2037 insertions, 512 deletions
@@ -1,5 +1,41 @@ 2002-12-31 Marco Pesenti Gritti <marco@it.gnome.org> + * embed/mozilla/FilePicker.cpp: + * embed/mozilla/FilePicker.h: + * embed/mozilla/mozilla-embed-shell.cpp: + + Resync with galeon. + + * data/epiphany.schemas.in: + * lib/ephy-bonobo-extensions.c: (ephy_bonobo_add_numbered_widget): + * lib/ephy-bonobo-extensions.h: + * lib/toolbar/Makefile.am: + * lib/toolbar/ephy-tbi-std-toolitem.c: + (ephy_tbi_std_toolitem_init), + (ephy_tbi_std_toolitem_get_icon_impl), + (ephy_tbi_std_toolitem_get_name_human_impl), + (ephy_tbi_std_toolitem_to_string_impl), + (ephy_tbi_std_toolitem_add_to_bonobo_tb_impl), + (ephy_tbi_std_toolitem_parse_properties_impl), + (ephy_tbi_std_toolitem_set_item): + * lib/toolbar/ephy-tbi-std-toolitem.h: + * lib/toolbar/ephy-toolbar-item-factory.c: + (ephy_tb_item_factory_init), + (ephy_toolbar_item_create_from_string), + (ephy_toolbar_item_register_type): + * lib/toolbar/ephy-toolbar-item-factory.h: + * src/Makefile.am: + * src/toolbar.c: (toolbar_class_init), (toolbar_set_property), + (toolbar_get_widgets), (toolbar_init), (toolbar_finalize), + (toolbar_navigation_button_set_sensitive), + (toolbar_button_set_sensitive): + * src/window-commands.c: + + Resync with galeon. Now we use a widget for navigation + buttons. + +2002-12-31 Marco Pesenti Gritti <marco@it.gnome.org> + * data/glade/prefs-dialog.glade: Remove hidden filtering page. diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in index 7450fefc7..f45104907 100644 --- a/data/epiphany.schemas.in +++ b/data/epiphany.schemas.in @@ -322,7 +322,7 @@ <applyto>/apps/epiphany/interface/toolbar_setup</applyto> <owner>epiphany</owner> <type>string</type> - <default>back=std_toolitem(item=back);back_history=navigation_history(direction=back);forward=std_toolitem(item=forward);forward_history=navigation_history(direction=forward);stop=std_toolitem(item=stop);reload=std_toolitem(item=reload);home_separator=separator;home=std_toolitem(item=home);favicons_separator=separator;favicon=favicon;location=location;spinner=spinner;</default> + <default>back_menu=navigation_button(direction=back,arrow=TRUE);forward_menu=navigation_button(direction=forward,arrow=TRUE);stop=std_toolitem(item=stop);reload=std_toolitem(item=reload);home_separator=separator;home=std_toolitem(item=home);favicons_separator=separator;favicon=favicon;location=location;spinner=spinner;</default> <locale name="C"> <short>Toolbar setup</short> <long>The list of controls that will be present in the toolbar. You should edit diff --git a/embed/mozilla/FilePicker.cpp b/embed/mozilla/FilePicker.cpp index baae069ef..6ef57d503 100644 --- a/embed/mozilla/FilePicker.cpp +++ b/embed/mozilla/FilePicker.cpp @@ -36,6 +36,7 @@ #include "ephy-gui.h" #include "eel-gconf-extensions.h" +#include <glib/gconvert.h> #include <gtk/gtkmain.h> #include <gtk/gtksignal.h> #include <gtk/gtkmenu.h> @@ -74,20 +75,17 @@ #include "FilePicker.h" #include "MozillaPrivate.h" -void filePicker_save_content_cb(GtkToggleButton *aButton, - GFilePicker *aFilePicker); - /* Implementation file */ NS_IMPL_ISUPPORTS1(GFilePicker, nsIFilePicker) -GFilePicker::GFilePicker(PRBool showContentCheck, FileFormat *fileFormats) : - mSaveContent(PR_FALSE) +GFilePicker::GFilePicker(PRBool aShowContentCheck, FileFormat *aFileFormats) : + mShowContentCheck(aShowContentCheck), + mSaveContentCheck(NULL), + mFileFormats(aFileFormats) { NS_INIT_ISUPPORTS(); - /* member initializers and constructor code */ - mShowContentCheck = showContentCheck; - mFileFormats = fileFormats; + /* member initializers and constructor code */ mFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); mDisplayDirectory = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); mDisplayDirectory->InitWithNativePath(nsDependentCString(g_get_home_dir())); @@ -147,13 +145,28 @@ NS_IMETHODIMP GFilePicker::SetFilterIndex(PRInt32 aFilterIndex) /* attribute wstring defaultString; */ NS_IMETHODIMP GFilePicker::GetDefaultString(PRUnichar * *aDefaultString) { - *aDefaultString = ToNewUnicode(NS_ConvertUTF8toUCS2(mDefaultString)); + guint bytesRead(0), bytesWritten(0); + gchar *utf8DefaultString = g_filename_to_utf8(mDefaultString.get(), -1, + &bytesRead, + &bytesWritten, NULL); + + *aDefaultString = ToNewUnicode(NS_ConvertUTF8toUCS2(utf8DefaultString)); + g_free(utf8DefaultString); + return NS_OK; } NS_IMETHODIMP GFilePicker::SetDefaultString(const PRUnichar *aDefaultString) { if (aDefaultString) - mDefaultString = NS_ConvertUCS2toUTF8(aDefaultString); + { + guint bytesRead(0), bytesWritten(0); + gchar *localeDefaultString = + g_filename_from_utf8(NS_ConvertUCS2toUTF8(aDefaultString).get(), + -1, &bytesRead, + &bytesWritten, NULL); + mDefaultString = localeDefaultString; + g_free(localeDefaultString); + } else mDefaultString = ""; return NS_OK; @@ -244,14 +257,10 @@ NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval) gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(mFileSelector)->action_area), bbox, TRUE, TRUE, 0); - GtkWidget *saveContent = + mSaveContentCheck = gtk_check_button_new_with_label(_("Save with content")); - g_signal_connect(G_OBJECT(saveContent), - "clicked", - G_CALLBACK(filePicker_save_content_cb), - (gpointer)this); - gtk_box_pack_start(GTK_BOX(bbox), saveContent, + gtk_box_pack_start(GTK_BOX(bbox), mSaveContentCheck, FALSE, FALSE, 0); gtk_widget_show_all(bbox); @@ -447,25 +456,28 @@ NS_METHOD GFilePicker::HandleFilePickerResult(PRInt16 *retval) if (mFormatChooser) { - gint i = 0; GtkWidget *menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(mFormatChooser)); - GList *iterator = GTK_MENU_SHELL(menu)->children; GtkWidget *selected = gtk_menu_get_active (GTK_MENU(menu)); - while (iterator) + gint i(0); + for (GList *iterator = GTK_MENU_SHELL(menu)->children ; + iterator ; iterator = iterator->next, i++) { if (iterator->data == selected) { mSelectedFileFormat = i; break; } - iterator = iterator->next; - i++; } } - *retval = mSaveContent ? returnOKSaveContent : returnOK; + if (GTK_IS_TOGGLE_BUTTON(mSaveContentCheck)) + *retval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mSaveContentCheck)) ? + returnOKSaveContent : returnOK; + else + *retval = returnOK; + return NS_OK; } @@ -492,14 +504,3 @@ nsresult NS_NewFilePickerFactory(nsIFactory** aFactory) return NS_OK; } - -//////////////////////////////////////////////////////////////////////////////// -// begin FileSelector callbacks. -//////////////////////////////////////////////////////////////////////////////// - -void filePicker_save_content_cb(GtkToggleButton *aButton, - GFilePicker *aFilePicker) -{ - aFilePicker->mSaveContent = gtk_toggle_button_get_active (aButton) ? - PR_TRUE : PR_FALSE; -} diff --git a/embed/mozilla/FilePicker.h b/embed/mozilla/FilePicker.h index 93c025637..7433b8b2d 100644 --- a/embed/mozilla/FilePicker.h +++ b/embed/mozilla/FilePicker.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef FILE_PICKER_H -#define FILE_PICKER_H +#ifndef __FilePicker_h +#define __FilePicker_h #include "nsIFilePicker.h" #include "nsError.h" @@ -47,21 +47,20 @@ extern nsresult NS_NewFilePickerFactory(nsIFactory** aFactory); /* Header file */ class GFilePicker : public nsIFilePicker { - friend void filePicker_save_content_cb(GtkToggleButton *aButton, - GFilePicker *aFilePicker); public: NS_DECL_ISUPPORTS NS_DECL_NSIFILEPICKER - enum { returnOK = nsIFilePicker::returnOK, + enum { returnOK = nsIFilePicker::returnOK, returnCancel = nsIFilePicker::returnCancel, returnReplace = nsIFilePicker::returnReplace, returnOKSaveContent = 256 }; - GFilePicker(PRBool aShowContentCheck = PR_FALSE, FileFormat *aFileFormats = NULL); + GFilePicker(PRBool aShowContentCheck = PR_FALSE, + FileFormat *aFileFormats = nsnull); virtual ~GFilePicker(); /* additional members */ - NS_METHOD InitWithGtkWidget(GtkWidget *aParentWidget, + NS_METHOD InitWithGtkWidget(GtkWidget *aParentWidget, const char *aTitle, PRInt16 aMode); NS_METHOD SanityCheck(PRBool *retIsSane); @@ -82,11 +81,11 @@ class GFilePicker : public nsIFilePicker PRInt16 mMode; PRBool mShowContentCheck; - PRBool mSaveContent; - GtkWidget *mParentWidget; + GtkWidget *mParentWidget; GtkWidget *mFileSelector; GtkWidget *mFormatChooser; + GtkWidget *mSaveContentCheck; FileFormat *mFileFormats; }; diff --git a/embed/mozilla/mozilla-embed-shell.cpp b/embed/mozilla/mozilla-embed-shell.cpp index 00b3c390d..717985d45 100644 --- a/embed/mozilla/mozilla-embed-shell.cpp +++ b/embed/mozilla/mozilla-embed-shell.cpp @@ -1064,7 +1064,7 @@ impl_show_file_picker (EphyEmbedShell *shell, nsCOMPtr<nsILocalFile> dir = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); - dir->InitWithPath (NS_ConvertUTF8toUCS2(expanded_directory)); + dir->InitWithNativePath (nsDependentCString(expanded_directory)); g_free (expanded_directory); filePicker->InitWithGtkWidget (parentWidget, title, mode); @@ -1097,9 +1097,9 @@ impl_show_file_picker (EphyEmbedShell *shell, g_free (*ret_fullpath); nsCOMPtr<nsILocalFile> file; filePicker->GetFile (getter_AddRefs(file)); - nsAutoString tempFullPathStr; - file->GetPath (tempFullPathStr); - *ret_fullpath = g_strdup (NS_ConvertUCS2toUTF8(tempFullPathStr).get()); + nsCAutoString tempFullPathStr; + file->GetNativePath (tempFullPathStr); + *ret_fullpath = g_strdup (tempFullPathStr.get()); delete filePicker; return G_OK; } diff --git a/lib/ephy-bonobo-extensions.c b/lib/ephy-bonobo-extensions.c index e40b377cd..efc43ed60 100644 --- a/lib/ephy-bonobo-extensions.c +++ b/lib/ephy-bonobo-extensions.c @@ -677,3 +677,19 @@ ephy_bonobo_clear_path (BonoboUIComponent *uic, g_free (remove_wildcard); } } + +void +ephy_bonobo_add_numbered_widget (BonoboUIComponent *uic, GtkWidget *w, + guint index, const char *container_path) +{ + gchar *path = ephy_bonobo_get_numbered_menu_item_path (uic, container_path, index); + gchar *item_name = get_numbered_menu_item_name (index); + gchar *xml_string = g_strdup_printf ("<control name=\"%s\"/>", item_name); + + bonobo_ui_component_set (uic, container_path, xml_string, NULL); + bonobo_ui_component_widget_set (uic, path, w, NULL); + + g_free (path); + g_free (item_name); + g_free (xml_string); +} diff --git a/lib/ephy-bonobo-extensions.h b/lib/ephy-bonobo-extensions.h index 86bb977f9..be090711d 100644 --- a/lib/ephy-bonobo-extensions.h +++ b/lib/ephy-bonobo-extensions.h @@ -117,5 +117,7 @@ void ephy_bonobo_clear_path (BonoboUIComponent *uic, void ephy_bonobo_replace_path (BonoboUIComponent *uic, const gchar *path_src, const char *path_dst); +void ephy_bonobo_add_numbered_widget (BonoboUIComponent *uic, GtkWidget *w, + guint index, const char *container_path); #endif /* EPHY_BONOBO_EXTENSIONS_H */ diff --git a/lib/toolbar/Makefile.am b/lib/toolbar/Makefile.am index a6affaa04..eb2bcf687 100644 --- a/lib/toolbar/Makefile.am +++ b/lib/toolbar/Makefile.am @@ -38,4 +38,6 @@ libephytoolbar_la_SOURCES = \ ephy-toolbar-tree-model.h \ ephy-toolbar-tree-model.c \ ephy-toolbar-editor.h \ - ephy-toolbar-editor.c + ephy-toolbar-editor.c \ + ephy-tb-button.c \ + ephy-tb-button.h diff --git a/lib/toolbar/ephy-tb-button.c b/lib/toolbar/ephy-tb-button.c new file mode 100644 index 000000000..4b251a094 --- /dev/null +++ b/lib/toolbar/ephy-tb-button.c @@ -0,0 +1,746 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ephy-tb-button.h" +#include "ephy-gobject-misc.h" +#include "ephy-gui.h" +#include "ephy-marshal.h" +#include "eel-gconf-extensions.h" + +#include <libgnome/gnome-i18n.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkalignment.h> +#include <gtk/gtktoolbar.h> +#include <bonobo/bonobo-ui-toolbar.h> +#include <string.h> + +#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC); +//#define DEBUG_MSG(x) g_print x +#define DEBUG_MSG(x) + +/** + * Private data + */ +struct _EphyTbButtonPrivate +{ + gchar *label; + GtkWidget *image; + gboolean use_stock; + gchar *tooltip_text; + GtkMenu *menu; + GtkWidget *arrow_widget; + gboolean sensitive; + + GtkWidget *button; + GtkBox *button_box; + GtkLabel *label_wid; + gboolean priority; + + gboolean in_bonobo_toobar; + + GtkReliefStyle button_relief; + GtkOrientation orientation; + GtkToolbarStyle style_gtk; + BonoboUIToolbarStyle style_bonobo; + GtkIconSize icon_size; // TODO + gboolean show_tooltips; + GtkTooltips *tooltips; +}; + +/** + * Private functions, only availble from this file + */ +static void ephy_tb_button_class_init (EphyTbButtonClass *klass); +static void ephy_tb_button_init (EphyTbButton *b); +static void ephy_tb_button_finalize_impl (GObject *o); +static void ephy_tb_button_build (EphyTbButton *b); +static void ephy_tb_button_empty (EphyTbButton *b); +static void ephy_tb_button_parent_set_cb (GtkWidget *widget, GtkObject *old_parent, + EphyTbButton *tb); +static void ephy_tb_button_gtk_orientation_changed_cb (GtkToolbar *toolbar, GtkOrientation orientation, + EphyTbButton *b); +static void ephy_tb_button_gtk_style_changed_cb (GtkToolbar *toolbar, GtkToolbarStyle style, + EphyTbButton *b); +static void ephy_tb_button_bonobo_set_orientation_cb (BonoboUIToolbar *toolbar, GtkOrientation orientation, + EphyTbButton *b); +static void ephy_tb_button_bonobo_set_style_cb (BonoboUIToolbar *toolbar, EphyTbButton *b); +static gboolean ephy_tb_button_arrow_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, + EphyTbButton *b); +static gboolean ephy_tb_button_arrow_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, + EphyTbButton *b); +static gboolean ephy_tb_button_button_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, + EphyTbButton *b); +static void ephy_tb_button_button_popup_menu_cb (GtkWidget *w, EphyTbButton *b); +static void ephy_tb_button_menu_deactivated_cb (GtkMenuShell *ms, EphyTbButton *b); + + +static gpointer gtk_hbox_class; + +enum EphyTbButtonSignalsEnum { + EPHY_TB_BUTTON_MENU_ACTIVATED, + EPHY_TB_BUTTON_LAST_SIGNAL +}; +static gint EphyTbButtonSignals[EPHY_TB_BUTTON_LAST_SIGNAL]; + +/** + * TbButton object + */ + +MAKE_GET_TYPE (ephy_tb_button, "EphyTbButton", EphyTbButton, ephy_tb_button_class_init, + ephy_tb_button_init, GTK_TYPE_HBOX); + +static void +ephy_tb_button_class_init (EphyTbButtonClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = ephy_tb_button_finalize_impl; + gtk_hbox_class = g_type_class_peek_parent (klass); + + EphyTbButtonSignals[EPHY_TB_BUTTON_MENU_ACTIVATED] = g_signal_new ( + "menu-activated", G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP, + G_STRUCT_OFFSET (EphyTbButtonClass, menu_activated), + NULL, NULL, + ephy_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +ephy_tb_button_init (EphyTbButton *tb) +{ + EphyTbButtonPrivate *p = g_new0 (EphyTbButtonPrivate, 1); + tb->priv = p; + p->label = g_strdup (""); + p->tooltip_text = g_strdup (""); + + p->button_relief = GTK_RELIEF_NORMAL; + p->orientation = GTK_ORIENTATION_HORIZONTAL; + p->style_gtk = GTK_TOOLBAR_BOTH_HORIZ; + p->style_bonobo = BONOBO_UI_TOOLBAR_STYLE_PRIORITY_TEXT; + p->icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR; + p->show_tooltips = TRUE; + + g_signal_connect (tb, "parent-set", + G_CALLBACK (ephy_tb_button_parent_set_cb), tb); +} + +EphyTbButton * +ephy_tb_button_new (void) +{ + EphyTbButton *ret = g_object_new (EPHY_TYPE_TB_BUTTON, NULL); + return ret; +} + +static void +ephy_tb_button_finalize_impl (GObject *o) +{ + EphyTbButton *it = EPHY_TB_BUTTON (o); + EphyTbButtonPrivate *p = it->priv; + + ephy_tb_button_empty (it); + + if (p->image) + { + g_object_unref (p->image); + } + + if (p->tooltips) + { + g_object_unref (p->tooltips); + } + + if (p->menu) + { + g_object_unref (p->menu); + } + + if (p->arrow_widget) + { + g_object_unref (p->arrow_widget); + } + + g_free (p); + + DEBUG_MSG (("EphyTbButton finalized\n")); + + G_OBJECT_CLASS (gtk_hbox_class)->finalize (o); +} + +void +ephy_tb_button_set_label (EphyTbButton *b, const gchar *text) +{ + EphyTbButtonPrivate *p = b->priv; + g_free (p->label); + p->label = g_strdup (text); + DEBUG_MSG (("EphyTbButton label set to '%s'\n", p->label)); + if (!p->label_wid || p->use_stock) + { + ephy_tb_button_build (b); + } + else + { + gtk_label_set_text (p->label_wid, p->label); + } +} + +void +ephy_tb_button_set_tooltip_text (EphyTbButton *b, const gchar *text) +{ + EphyTbButtonPrivate *p = b->priv; + g_free (p->tooltip_text); + p->tooltip_text = g_strdup (text); + + if (!p->tooltips || !p->button) + { + ephy_tb_button_build (b); + } + else + { + gtk_tooltips_set_tip (p->tooltips, p->button, + p->tooltip_text, p->tooltip_text); + } +} + +/* this function comes directly from gtktoolbar.c */ +static gchar * +elide_underscores (const gchar *original) +{ + gchar *q, *result; + const gchar *p; + gboolean last_underscore; + + q = result = g_malloc (strlen (original) + 1); + last_underscore = FALSE; + + for (p = original; *p; p++) + { + if (!last_underscore && *p == '_') + { + last_underscore = TRUE; + } + else + { + last_underscore = FALSE; + *q++ = *p; + } + } + + *q = '\0'; + + return result; +} + +static void +ephy_tb_button_build (EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + GtkWidget *align; + GtkWidget *image; + GtkStockItem stock_item; + gboolean really_use_stock = p->use_stock && gtk_stock_lookup (p->label, &stock_item); + gboolean show_image = p->label[0] == '\0' + || (p->in_bonobo_toobar && p->style_bonobo != BONOBO_UI_TOOLBAR_STYLE_TEXT_ONLY) + || (!p->in_bonobo_toobar && p->style_gtk != GTK_TOOLBAR_TEXT); + gboolean show_label = !show_image + || (p->priority && ((p->in_bonobo_toobar && p->style_bonobo == BONOBO_UI_TOOLBAR_STYLE_PRIORITY_TEXT) + || (!p->in_bonobo_toobar && p->style_gtk == GTK_TOOLBAR_BOTH_HORIZ))) + || (!p->in_bonobo_toobar + && (p->style_gtk == GTK_TOOLBAR_BOTH + || p->style_gtk == GTK_TOOLBAR_TEXT + /* CHECK: what about GTK_TOOLBAR_BOTH_HORIZ? */ )) + || (p->in_bonobo_toobar + && (p->style_bonobo == BONOBO_UI_TOOLBAR_STYLE_ICONS_AND_TEXT + || p->style_bonobo == BONOBO_UI_TOOLBAR_STYLE_TEXT_ONLY)); + + ephy_tb_button_empty (b); + + if (!p->button) + { + p->button = gtk_button_new (); + g_object_ref (p->button); + gtk_widget_show (p->button); + gtk_box_pack_start_defaults (GTK_BOX (b), p->button); + } + + gtk_button_set_relief (GTK_BUTTON (p->button), p->button_relief); + gtk_widget_set_sensitive (p->button, p->sensitive); + if (p->tooltips) + { + gtk_tooltips_set_tip (p->tooltips, p->button, + p->tooltip_text, p->tooltip_text); + } + g_signal_connect (p->button, "button_press_event", + G_CALLBACK (ephy_tb_button_button_button_press_event_cb), b); + g_signal_connect (p->button, "popup_menu", + G_CALLBACK (ephy_tb_button_button_popup_menu_cb), b); + + align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + gtk_widget_show (align); + gtk_container_add (GTK_CONTAINER (p->button), align); + + if ((p->in_bonobo_toobar && p->style_bonobo == BONOBO_UI_TOOLBAR_STYLE_ICONS_AND_TEXT) + || (!p->in_bonobo_toobar && p->style_gtk == GTK_TOOLBAR_BOTH) + || p->orientation == GTK_ORIENTATION_VERTICAL) + { + p->button_box = GTK_BOX (gtk_vbox_new (FALSE, 2)); + } + else + { + p->button_box = GTK_BOX (gtk_hbox_new (FALSE, 2)); + } + g_object_ref (p->button_box); + gtk_widget_show (GTK_WIDGET (p->button_box)); + gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (p->button_box)); + + if (!p->image && really_use_stock && show_image) + { + image = gtk_image_new_from_stock (p->label, p->icon_size); + } + else + { + image = p->image; + } + + if (image) + { + if (show_image) + { + gtk_box_pack_start_defaults (p->button_box, GTK_WIDGET (image)); + gtk_widget_show (image); + } + } + else + { + show_label = TRUE; + } + + if (show_label) + { + p->label_wid = GTK_LABEL (gtk_label_new (p->label)); + g_object_ref (p->label_wid); + + if (really_use_stock) + { + gchar *l = elide_underscores (stock_item.label); + gtk_label_set_text (p->label_wid, l); + g_free (l); + } + + gtk_widget_show (GTK_WIDGET (p->label_wid)); + gtk_box_pack_end_defaults (p->button_box, GTK_WIDGET (p->label_wid)); + } + + DEBUG_MSG (("EphyTbButton built, label='%s'\n", p->label)); +} + +void +ephy_tb_button_set_priority (EphyTbButton *b, gboolean priority) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->priority != priority) + { + p->priority = priority; + ephy_tb_button_build (b); + } +} + +void +ephy_tb_button_set_image (EphyTbButton *b, GtkWidget *image) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->image) + { + g_object_unref (p->image); + } + p->image = image ? g_object_ref (image) : NULL; + ephy_tb_button_build (b); +} + +void +ephy_tb_button_set_show_arrow (EphyTbButton *b, gboolean value) +{ + EphyTbButtonPrivate *p = b->priv; + + if (p->arrow_widget && !value) + { + if (p->arrow_widget->parent == GTK_WIDGET (b)) + { + gtk_container_remove (GTK_CONTAINER (b), p->arrow_widget); + } + g_object_unref (p->arrow_widget); + p->arrow_widget = NULL; + } + else if (!p->arrow_widget && value) + { + p->arrow_widget = gtk_toggle_button_new (); + gtk_button_set_relief (GTK_BUTTON (p->arrow_widget), GTK_RELIEF_NONE); + + gtk_container_add (GTK_CONTAINER (p->arrow_widget), + gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT)); + + g_object_ref (p->arrow_widget); + gtk_object_sink (GTK_OBJECT (p->arrow_widget)); + + g_signal_connect (p->arrow_widget, "key_press_event", + G_CALLBACK (ephy_tb_button_arrow_key_press_event_cb), + b); + + g_signal_connect (p->arrow_widget, "button_press_event", + G_CALLBACK (ephy_tb_button_arrow_button_press_event_cb), + b); + + gtk_widget_show_all (p->arrow_widget); + gtk_box_pack_end_defaults (GTK_BOX (b), p->arrow_widget); + gtk_widget_set_sensitive (p->arrow_widget, value); + } +} + +void +ephy_tb_button_set_enable_menu (EphyTbButton *b, gboolean value) +{ + EphyTbButtonPrivate *p = b->priv; + if (value && !p->menu) + { + p->menu = GTK_MENU (gtk_menu_new ()); + g_signal_connect (p->menu, "deactivate", + G_CALLBACK (ephy_tb_button_menu_deactivated_cb), b); + } + else if (!value && p->menu) + { + g_object_unref (p->menu); + p->menu = FALSE; + } + +} + +GtkMenuShell * +ephy_tb_button_get_menu (EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + return p->menu ? GTK_MENU_SHELL (p->menu) : NULL; +} + +GtkButton * +ephy_tb_button_get_button (EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + if (!p->button) + { + ephy_tb_button_build (b); + } + return GTK_BUTTON (p->button); +} + +void +ephy_tb_button_set_use_stock (EphyTbButton *b, gboolean value) +{ + EphyTbButtonPrivate *p = b->priv; + if (value != p->use_stock) + { + p->use_stock = value; + ephy_tb_button_build (b); + } +} + +static void +ephy_tb_button_empty (EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + + if (p->button) + { + if (GTK_BIN (p->button)->child) + { + gtk_container_remove (GTK_CONTAINER (p->button), GTK_BIN (p->button)->child); + } + } + + if (p->button_box) + { + g_object_unref (p->button_box); + p->button_box = NULL; + } + + if (p->label_wid) + { + g_object_unref (p->label_wid); + p->label_wid = NULL; + } +} + +static void +ephy_tb_button_parent_set_cb (GtkWidget *widget, GtkObject *old_parent, EphyTbButton *tb) +{ + EphyTbButtonPrivate *p = tb->priv; + GtkWidget *new_parent = widget->parent; + + DEBUG_MSG (("EphyTbButton parent changed (widget=%p, button=%p, old=%p, new=%p)\n", + widget, tb, old_parent, new_parent)); + + if (new_parent) + { + GtkToolbar *gtktb = NULL; + BonoboUIToolbar *btb = NULL; + while (new_parent && !gtktb && !btb) + { + DEBUG_MSG (("new_parent ia a %s\n", g_type_name_from_instance ((void *) new_parent))); + + if (GTK_IS_TOOLBAR (new_parent)) + { + gtktb = GTK_TOOLBAR (new_parent); + } + else if (BONOBO_IS_UI_TOOLBAR (new_parent)) + { + btb = BONOBO_UI_TOOLBAR (new_parent); + } + else + { + g_signal_connect (new_parent, "parent_set", + G_CALLBACK (ephy_tb_button_parent_set_cb), tb); + } + new_parent = new_parent->parent; + } + + if (gtktb) + { + DEBUG_MSG (("EphyTbButton getting style from a GtkToolbar (%p)\n", gtktb)); + p->in_bonobo_toobar = FALSE; + + gtk_widget_ensure_style (GTK_WIDGET (gtktb)); + gtk_widget_style_get (GTK_WIDGET (gtktb), "button_relief", &p->button_relief, NULL); + + p->orientation = gtk_toolbar_get_orientation (gtktb); + p->style_gtk = gtk_toolbar_get_style (gtktb); + p->icon_size = gtk_toolbar_get_icon_size (gtktb); + p->show_tooltips = gtk_toolbar_get_tooltips (gtktb); + + if (p->tooltips) + { + g_object_unref (p->tooltips); + } + p->tooltips = gtk_tooltips_new (); + if (p->show_tooltips) + { + gtk_tooltips_enable (p->tooltips); + } + else + { + gtk_tooltips_disable (p->tooltips); + } + g_object_ref (p->tooltips); + gtk_object_sink (GTK_OBJECT (p->tooltips)); + + g_signal_connect (gtktb, "orientation-changed", + G_CALLBACK (ephy_tb_button_gtk_orientation_changed_cb), tb); + g_signal_connect (gtktb, "style-changed", + G_CALLBACK (ephy_tb_button_gtk_style_changed_cb), tb); + + ephy_tb_button_build (tb); + } + + if (btb) + { + DEBUG_MSG (("EphyTbButton getting style from a BonoboUIToolbar (%p)\n", btb)); + p->in_bonobo_toobar = TRUE; + + p->button_relief = GTK_RELIEF_NONE; + + p->orientation = bonobo_ui_toolbar_get_orientation (btb); + p->style_bonobo = bonobo_ui_toolbar_get_style (btb); + //p->icon_size = ???; + p->show_tooltips = TRUE; + + if (p->tooltips) + { + g_object_unref (p->tooltips); + } + p->tooltips = bonobo_ui_toolbar_get_tooltips (btb); + g_object_ref (p->tooltips); + + g_signal_connect (btb, "set-orientation", + G_CALLBACK (ephy_tb_button_bonobo_set_orientation_cb), tb); + g_signal_connect (btb, "set-style", + G_CALLBACK (ephy_tb_button_bonobo_set_style_cb), tb); + + ephy_tb_button_build (tb); + } + } + else + { + while (old_parent) + { + g_signal_handlers_disconnect_matched (old_parent, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, tb); + if (GTK_IS_WIDGET (old_parent)) + { + old_parent = GTK_WIDGET (old_parent)->parent + ? GTK_OBJECT (GTK_WIDGET (old_parent)->parent) + : NULL; + } + else + { + old_parent = NULL; + } + } + } +} + +static void +ephy_tb_button_gtk_orientation_changed_cb (GtkToolbar *toolbar, GtkOrientation orientation, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->orientation != orientation) + { + p->orientation = orientation; + ephy_tb_button_build (b); + } +} + +static void +ephy_tb_button_gtk_style_changed_cb (GtkToolbar *toolbar, GtkToolbarStyle style, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->style_gtk != style) + { + p->style_gtk = style; + ephy_tb_button_build (b); + } +} + +static void +ephy_tb_button_bonobo_set_orientation_cb (BonoboUIToolbar *toolbar, GtkOrientation orientation, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->orientation != orientation) + { + p->orientation = orientation; + ephy_tb_button_build (b); + } +} + +static void +ephy_tb_button_bonobo_set_style_cb (BonoboUIToolbar *toolbar, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + BonoboUIToolbarStyle style = bonobo_ui_toolbar_get_style (toolbar); + if (style != p->style_bonobo) + { + p->style_bonobo = style; + ephy_tb_button_build (b); + } +} + +static void +ephy_tb_button_popup_menu_under_arrow (EphyTbButton *b, GdkEventButton *event) +{ + EphyTbButtonPrivate *p = b->priv; + + if (p->menu) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p->arrow_widget), TRUE); + g_signal_emit (b, EphyTbButtonSignals[EPHY_TB_BUTTON_MENU_ACTIVATED], 0); + gtk_menu_popup (p->menu, NULL, NULL, ephy_gui_menu_position_under_widget, p->arrow_widget, + event ? event->button : 0, + event ? event->time : gtk_get_current_event_time ()); + } +} + +static void +ephy_tb_button_menu_deactivated_cb (GtkMenuShell *ms, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + if (p->arrow_widget) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p->arrow_widget), FALSE); + } +} + +static gboolean +ephy_tb_button_arrow_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, EphyTbButton *b) +{ + ephy_tb_button_popup_menu_under_arrow (b, event); + return TRUE; +} + +static gboolean +ephy_tb_button_arrow_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, EphyTbButton *b) +{ + if (event->keyval == GDK_space + || event->keyval == GDK_KP_Space + || event->keyval == GDK_Return + || event->keyval == GDK_KP_Enter + || event->keyval == GDK_Menu) + { + ephy_tb_button_popup_menu_under_arrow (b, NULL); + } + + return FALSE; +} + +static gboolean +ephy_tb_button_button_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, + EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + + if (event->button == 3 && p->menu) + { + g_signal_emit (b, EphyTbButtonSignals[EPHY_TB_BUTTON_MENU_ACTIVATED], 0); + gtk_menu_popup (p->menu, NULL, NULL, NULL, b, + event ? event->button : 0, + event ? event->time : gtk_get_current_event_time ()); + return TRUE; + } + + return FALSE; +} + +static void +ephy_tb_button_button_popup_menu_cb (GtkWidget *w, EphyTbButton *b) +{ + EphyTbButtonPrivate *p = b->priv; + + g_signal_emit (b, EphyTbButtonSignals[EPHY_TB_BUTTON_MENU_ACTIVATED], 0); + gtk_menu_popup (p->menu, NULL, NULL, + ephy_gui_menu_position_under_widget, b, 0, gtk_get_current_event_time ()); +} + +void +ephy_tb_button_set_sensitivity (EphyTbButton *b, gboolean value) +{ + EphyTbButtonPrivate *p = b->priv; + + p->sensitive = value; + + if (!p->button) + { + ephy_tb_button_build (b); + } + else + { + gtk_widget_set_sensitive (p->button, value); + if (p->arrow_widget) + { + gtk_widget_set_sensitive (p->arrow_widget, value); + } + } +} + diff --git a/lib/toolbar/ephy-tb-button.h b/lib/toolbar/ephy-tb-button.h new file mode 100644 index 000000000..5d3d9616a --- /dev/null +++ b/lib/toolbar/ephy-tb-button.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_TB_BUTTON_H +#define EPHY_TB_BUTTON_H + +#include <gtk/gtkhbox.h> +#include <gtk/gtkmenushell.h> +#include <gtk/gtkbutton.h> + +G_BEGIN_DECLS + +/* object forward declarations */ + +typedef struct _EphyTbButton EphyTbButton; +typedef struct _EphyTbButtonClass EphyTbButtonClass; +typedef struct _EphyTbButtonPrivate EphyTbButtonPrivate; + +/** + * TbButton object + */ + +#define EPHY_TYPE_TB_BUTTON (ephy_tb_button_get_type()) +#define EPHY_TB_BUTTON(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TB_BUTTON,\ + EphyTbButton)) +#define EPHY_TB_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TB_BUTTON,\ + EphyTbButtonClass)) +#define EPHY_IS_TB_BUTTON(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TB_BUTTON)) +#define EPHY_IS_TB_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TB_BUTTON)) +#define EPHY_TB_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TB_BUTTON,\ + EphyTbButtonClass)) + +struct _EphyTbButtonClass +{ + GtkHBoxClass parent_class; + + void (*menu_activated) (EphyTbButton *b); +}; + +/* Remember: fields are public read-only */ +struct _EphyTbButton +{ + GtkHBox parent_object; + EphyTbButtonPrivate *priv; +}; + +/* this class is abstract */ + +GType ephy_tb_button_get_type (void); +EphyTbButton * ephy_tb_button_new (void); +void ephy_tb_button_set_label (EphyTbButton *b, const gchar *text); +void ephy_tb_button_set_use_stock (EphyTbButton *b, gboolean value); +void ephy_tb_button_set_priority (EphyTbButton *b, gboolean priority); +void ephy_tb_button_set_image (EphyTbButton *b, GtkWidget *image); +void ephy_tb_button_set_tooltip_text (EphyTbButton *b, const gchar *text); +void ephy_tb_button_set_show_arrow (EphyTbButton *b, gboolean value); +void ephy_tb_button_set_enable_menu (EphyTbButton *b, gboolean value); +GtkMenuShell * ephy_tb_button_get_menu (EphyTbButton *b); +GtkButton * ephy_tb_button_get_button (EphyTbButton *b); +void ephy_tb_button_set_sensitivity (EphyTbButton *b, gboolean value); + +G_END_DECLS + +#endif diff --git a/lib/toolbar/ephy-tbi-std-toolitem.c b/lib/toolbar/ephy-tbi-std-toolitem.c index deb468ecb..4b7f3864c 100644 --- a/lib/toolbar/ephy-tbi-std-toolitem.c +++ b/lib/toolbar/ephy-tbi-std-toolitem.c @@ -97,7 +97,7 @@ ephy_tbi_std_toolitem_init (EphyTbiStdToolitem *tb) EphyTbiStdToolitemPrivate *p = g_new0 (EphyTbiStdToolitemPrivate, 1); tb->priv = p; - p->item = EPHY_TBI_STD_TOOLITEM_BACK; + p->item = EPHY_TBI_STD_TOOLITEM_STOP; } EphyTbiStdToolitem * @@ -137,31 +137,16 @@ ephy_tbi_std_toolitem_get_icon_impl (EphyTbItem *i) { EphyTbiStdToolitemPrivate *p = EPHY_TBI_STD_TOOLITEM (i)->priv; - static GdkPixbuf *pb_up = NULL; - static GdkPixbuf *pb_back = NULL; - static GdkPixbuf *pb_forward = NULL; static GdkPixbuf *pb_stop = NULL; static GdkPixbuf *pb_reload = NULL; static GdkPixbuf *pb_home = NULL; static GdkPixbuf *pb_go = NULL; static GdkPixbuf *pb_new = NULL; - - if (!pb_up) + + if (!pb_stop) { /* what's the easier way? */ GtkWidget *b = gtk_spin_button_new_with_range (0, 1, 0.5); - pb_up = gtk_widget_render_icon (b, - GTK_STOCK_GO_UP, - GTK_ICON_SIZE_SMALL_TOOLBAR, - NULL); - pb_back = gtk_widget_render_icon (b, - GTK_STOCK_GO_BACK, - GTK_ICON_SIZE_SMALL_TOOLBAR, - NULL); - pb_forward = gtk_widget_render_icon (b, - GTK_STOCK_GO_FORWARD, - GTK_ICON_SIZE_SMALL_TOOLBAR, - NULL); pb_stop = gtk_widget_render_icon (b, GTK_STOCK_STOP, GTK_ICON_SIZE_SMALL_TOOLBAR, @@ -187,15 +172,6 @@ ephy_tbi_std_toolitem_get_icon_impl (EphyTbItem *i) switch (p->item) { - case EPHY_TBI_STD_TOOLITEM_BACK: - return g_object_ref (pb_back); - break; - case EPHY_TBI_STD_TOOLITEM_FORWARD: - return g_object_ref (pb_forward); - break; - case EPHY_TBI_STD_TOOLITEM_UP: - return g_object_ref (pb_up); - break; case EPHY_TBI_STD_TOOLITEM_STOP: return g_object_ref (pb_stop); break; @@ -211,6 +187,9 @@ ephy_tbi_std_toolitem_get_icon_impl (EphyTbItem *i) case EPHY_TBI_STD_TOOLITEM_NEW: return g_object_ref (pb_new); break; + case EPHY_TBI_STD_TOOLITEM_ERROR: + return NULL; + break; default: g_assert_not_reached (); return NULL; @@ -225,15 +204,6 @@ ephy_tbi_std_toolitem_get_name_human_impl (EphyTbItem *i) switch (p->item) { - case EPHY_TBI_STD_TOOLITEM_BACK: - ret = _("Back"); - break; - case EPHY_TBI_STD_TOOLITEM_FORWARD: - ret = _("Forward"); - break; - case EPHY_TBI_STD_TOOLITEM_UP: - ret = _("Up"); - break; case EPHY_TBI_STD_TOOLITEM_STOP: ret = _("Stop"); break; @@ -249,6 +219,9 @@ ephy_tbi_std_toolitem_get_name_human_impl (EphyTbItem *i) case EPHY_TBI_STD_TOOLITEM_NEW: ret = _("New"); break; + case EPHY_TBI_STD_TOOLITEM_ERROR: + ret = "Erroneous button"; + break; default: g_assert_not_reached (); ret = "unknown"; @@ -267,15 +240,6 @@ ephy_tbi_std_toolitem_to_string_impl (EphyTbItem *i) switch (p->item) { - case EPHY_TBI_STD_TOOLITEM_BACK: - sitem = "back"; - break; - case EPHY_TBI_STD_TOOLITEM_FORWARD: - sitem = "forward"; - break; - case EPHY_TBI_STD_TOOLITEM_UP: - sitem = "up"; - break; case EPHY_TBI_STD_TOOLITEM_STOP: sitem = "stop"; break; @@ -291,6 +255,9 @@ ephy_tbi_std_toolitem_to_string_impl (EphyTbItem *i) case EPHY_TBI_STD_TOOLITEM_NEW: sitem = "new"; break; + case EPHY_TBI_STD_TOOLITEM_ERROR: + sitem = "error"; + break; default: g_assert_not_reached (); sitem = "unknown"; @@ -330,28 +297,6 @@ ephy_tbi_std_toolitem_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *u switch (p->item) { - case EPHY_TBI_STD_TOOLITEM_BACK: - xml_item = g_strdup_printf - ("<toolitem name=\"Back\" " - "label=\"%s\" " - "pixtype=\"stock\" pixname=\"gtk-go-back\" " - "priority=\"1\" " - "verb=\"GoBack\"/>", _("Back"));; - break; - case EPHY_TBI_STD_TOOLITEM_FORWARD: - xml_item = g_strdup_printf - ("<toolitem name=\"Forward\" " - "label=\"%s\" " - "pixtype=\"stock\" pixname=\"gtk-go-forward\" " - "verb=\"GoForward\"/>", _("Forward")); - break; - case EPHY_TBI_STD_TOOLITEM_UP: - xml_item = g_strdup_printf - ("<toolitem name=\"Up\" " - "label=\"%s\" " - "pixtype=\"stock\" pixname=\"gtk-go-up\" " - "verb=\"GoUp\"/>", _("Up"));; - break; case EPHY_TBI_STD_TOOLITEM_STOP: xml_item = g_strdup_printf ("<toolitem name=\"Stop\" " @@ -388,7 +333,14 @@ ephy_tbi_std_toolitem_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *u "pixtype=\"stock\" pixname=\"gtk-new\" " "verb=\"FileNew\"/>", _("New"));; break; - + case EPHY_TBI_STD_TOOLITEM_ERROR: + xml_item = g_strdup_printf + ("<toolitem name=\"Error\" " + "label=\"%s\" " + "pixtype=\"stock\" pixname=\"gtk-cancel\" " + "priority=\"1\" " + "verb=\"ErrorVerb\"/>", "Erroneous button"); + break; default: g_assert_not_reached (); xml_item = g_strdup (""); @@ -412,19 +364,7 @@ ephy_tbi_std_toolitem_parse_properties_impl (EphyTbItem *it, const gchar *props) if (item_prop) { item_prop += strlen ("item="); - if (!strncmp (item_prop, "back", 4)) - { - ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_BACK); - } - else if (!strncmp (item_prop, "forward", 4)) - { - ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_FORWARD); - } - else if (!strncmp (item_prop, "up", 2)) - { - ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_UP); - } - else if (!strncmp (item_prop, "stop", 4)) + if (!strncmp (item_prop, "stop", 4)) { ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_STOP); } @@ -444,7 +384,10 @@ ephy_tbi_std_toolitem_parse_properties_impl (EphyTbItem *it, const gchar *props) { ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_NEW); } - + else + { + ephy_tbi_std_toolitem_set_item (a, EPHY_TBI_STD_TOOLITEM_ERROR); + } } } @@ -453,10 +396,7 @@ ephy_tbi_std_toolitem_set_item (EphyTbiStdToolitem *a, EphyTbiStdToolitemItem i) { EphyTbiStdToolitemPrivate *p = a->priv; - g_return_if_fail (i == EPHY_TBI_STD_TOOLITEM_UP - || i == EPHY_TBI_STD_TOOLITEM_BACK - || i == EPHY_TBI_STD_TOOLITEM_FORWARD - || i == EPHY_TBI_STD_TOOLITEM_STOP + g_return_if_fail (i == EPHY_TBI_STD_TOOLITEM_STOP || i == EPHY_TBI_STD_TOOLITEM_RELOAD || i == EPHY_TBI_STD_TOOLITEM_GO || i == EPHY_TBI_STD_TOOLITEM_HOME diff --git a/lib/toolbar/ephy-tbi-std-toolitem.h b/lib/toolbar/ephy-tbi-std-toolitem.h index 67073041f..c47d5d7ea 100644 --- a/lib/toolbar/ephy-tbi-std-toolitem.h +++ b/lib/toolbar/ephy-tbi-std-toolitem.h @@ -49,14 +49,12 @@ typedef struct _EphyTbiStdToolitemPrivate EphyTbiStdToolitemPrivate; EphyTbiStdToolitemClass)) typedef enum { - EPHY_TBI_STD_TOOLITEM_BACK, - EPHY_TBI_STD_TOOLITEM_FORWARD, - EPHY_TBI_STD_TOOLITEM_UP, EPHY_TBI_STD_TOOLITEM_STOP, EPHY_TBI_STD_TOOLITEM_RELOAD, EPHY_TBI_STD_TOOLITEM_HOME, EPHY_TBI_STD_TOOLITEM_GO, - EPHY_TBI_STD_TOOLITEM_NEW + EPHY_TBI_STD_TOOLITEM_NEW, + EPHY_TBI_STD_TOOLITEM_ERROR } EphyTbiStdToolitemItem; diff --git a/lib/toolbar/ephy-toolbar-item-factory.c b/lib/toolbar/ephy-toolbar-item-factory.c index 1637100ae..60cfbbc41 100644 --- a/lib/toolbar/ephy-toolbar-item-factory.c +++ b/lib/toolbar/ephy-toolbar-item-factory.c @@ -35,26 +35,42 @@ //#define DEBUG_MSG(x) g_print x #define DEBUG_MSG(x) -typedef EphyTbItem *(EphyTbItemConstructor) (void); - typedef struct { const char *type_name; - EphyTbItemConstructor *constructor; + EphyTbItemConstructor constructor; } EphyTbItemTypeInfo; -static EphyTbItemTypeInfo ephy_tb_item_known_types[] = +static EphyTbItemTypeInfo ephy_tb_item_default_types[] = { - { "std_toolitem", (EphyTbItemConstructor *) ephy_tbi_std_toolitem_new }, - { "navigation_history", (EphyTbItemConstructor *) ephy_tbi_navigation_history_new }, - { "zoom", (EphyTbItemConstructor *) ephy_tbi_zoom_new }, - { "location", (EphyTbItemConstructor *) ephy_tbi_location_new }, - { "spinner", (EphyTbItemConstructor *) ephy_tbi_spinner_new }, - { "favicon", (EphyTbItemConstructor *) ephy_tbi_favicon_new }, - { "separator", (EphyTbItemConstructor *) ephy_tbi_separator_new }, + { "std_toolitem", (EphyTbItemConstructor) ephy_tbi_std_toolitem_new }, + { "navigation_history", (EphyTbItemConstructor) ephy_tbi_navigation_history_new }, + { "zoom", (EphyTbItemConstructor) ephy_tbi_zoom_new }, + { "location", (EphyTbItemConstructor) ephy_tbi_location_new }, + { "spinner", (EphyTbItemConstructor) ephy_tbi_spinner_new }, + { "favicon", (EphyTbItemConstructor) ephy_tbi_favicon_new }, + { "separator", (EphyTbItemConstructor) ephy_tbi_separator_new }, { NULL, NULL } }; +static GHashTable *ephy_tb_item_known_types = NULL; + +static void +ephy_tb_item_factory_init (void) +{ + if (ephy_tb_item_known_types == NULL) + { + int i; + ephy_tb_item_known_types = g_hash_table_new (g_str_hash, g_str_equal); + + for (i = 0; ephy_tb_item_default_types[i].type_name; ++i) + { + ephy_toolbar_item_register_type (ephy_tb_item_default_types[i].type_name, + ephy_tb_item_default_types[i].constructor); + } + } +} + EphyTbItem * ephy_toolbar_item_create_from_string (const gchar *str) { @@ -66,7 +82,9 @@ ephy_toolbar_item_create_from_string (const gchar *str) const gchar *lpar; const gchar *rpar; const gchar *eq; - int i; + EphyTbItemConstructor constructor; + + ephy_tb_item_factory_init (); rest = str; @@ -104,21 +122,20 @@ ephy_toolbar_item_create_from_string (const gchar *str) props = NULL; } - DEBUG_MSG (("ephytoolbar_item_create_from_string id=%s type=%s props=%s\n", id, type, props)); + DEBUG_MSG (("ephy_toolbar_item_create_from_string id=%s type=%s props=%s\n", id, type, props)); + + constructor = g_hash_table_lookup (ephy_tb_item_known_types, type); - for (i = 0; ephy_tb_item_known_types[i].type_name; ++i) + if (constructor) { - if (!strcmp (type, ephy_tb_item_known_types[i].type_name)) + ret = constructor (); + if (id) + { + ephy_tb_item_set_id (ret, id); + } + if (props) { - ret = ephy_tb_item_known_types[i].constructor (); - if (id) - { - ephy_tb_item_set_id (ret, id); - } - if (props) - { - ephy_tb_item_parse_properties (ret, props); - } + ephy_tb_item_parse_properties (ret, props); } } @@ -143,16 +160,9 @@ ephy_toolbar_item_create_from_string (const gchar *str) return ret; } -GSList * -ephy_toolbar_list_item_types (void) +void +ephy_toolbar_item_register_type (const gchar *type, EphyTbItemConstructor constructor) { - int i; - GSList *ret = NULL; - for (i = 0; ephy_tb_item_known_types[i].type_name; ++i) - { - ret = g_slist_prepend (ret, - (gchar *) ephy_tb_item_known_types[i].type_name); - } - return ret; + ephy_tb_item_factory_init (); + g_hash_table_insert (ephy_tb_item_known_types, g_strdup (type), constructor); } - diff --git a/lib/toolbar/ephy-toolbar-item-factory.h b/lib/toolbar/ephy-toolbar-item-factory.h index e86179399..d613abeeb 100644 --- a/lib/toolbar/ephy-toolbar-item-factory.h +++ b/lib/toolbar/ephy-toolbar-item-factory.h @@ -23,8 +23,10 @@ G_BEGIN_DECLS +typedef EphyTbItem *(*EphyTbItemConstructor) (void); + EphyTbItem * ephy_toolbar_item_create_from_string (const gchar *str); -GSList * ephy_toolbar_list_item_types (void); +void ephy_toolbar_item_register_type (const gchar *type, EphyTbItemConstructor constructor); G_END_DECLS diff --git a/src/Makefile.am b/src/Makefile.am index 5ec49453d..cad9cd290 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,7 +79,11 @@ epiphany_SOURCES = \ ephy-favorites-menu.c \ ephy-favorites-menu.h \ ephy-history-model.c \ - ephy-history-model.h + ephy-history-model.h \ + ephy-tbi.c \ + ephy-tbi.h \ + ephy-navigation-button.c \ + ephy-navigation-button.h epiphany_LDADD = \ $(top_builddir)/embed/libephyembed.la \ diff --git a/src/ephy-navigation-button.c b/src/ephy-navigation-button.c new file mode 100644 index 000000000..f57de2690 --- /dev/null +++ b/src/ephy-navigation-button.c @@ -0,0 +1,614 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <libgnome/gnome-i18n.h> +#include "ephy-gobject-misc.h" +#include "ephy-marshal.h" +#include "ephy-tb-button.h" +#include "ephy-gui.h" +#include "ephy-string.h" +#include "ephy-navigation-button.h" +#include <gtk/gtkstock.h> +#include <string.h> + +#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC); +//#define DEBUG_MSG(x) g_print x +#define DEBUG_MSG(x) + +/** + * Private data + */ +struct _EphyNavigationButtonPrivate +{ + EphyTbButton *widget; + EphyNavigationDirection direction; + gboolean show_arrow; + gboolean sensitive; +}; + +enum +{ + TOOLBAR_ITEM_STYLE_PROP, + TOOLBAR_ITEM_ORIENTATION_PROP, + TOOLBAR_ITEM_WANT_LABEL_PROP +}; + +/** + * Private functions, only availble from this file + */ +static void ephy_navigation_button_class_init (EphyNavigationButtonClass *klass); +static void ephy_navigation_button_init (EphyNavigationButton *tb); +static void ephy_navigation_button_finalize_impl (GObject *o); +static GtkWidget * ephy_navigation_button_get_widget_impl (EphyTbItem *i); +static GdkPixbuf * ephy_navigation_button_get_icon_impl (EphyTbItem *i); +static gchar * ephy_navigation_button_get_name_human_impl (EphyTbItem *i); +static gchar * ephy_navigation_button_to_string_impl (EphyTbItem *i); +static EphyTbItem * ephy_navigation_button_clone_impl (EphyTbItem *i); +static void ephy_navigation_button_parse_properties_impl (EphyTbItem *i, const gchar *props); +static void ephy_navigation_button_menu_activated_cb (EphyTbButton *w, EphyNavigationButton *b); +static void ephy_navigation_button_clicked_cb (GtkWidget *w, EphyNavigationButton *b); + + +static gpointer ephy_tb_item_class; + +/** + * TbiZoom object + */ + +MAKE_GET_TYPE (ephy_navigation_button, "EphyNavigationButton", EphyNavigationButton, + ephy_navigation_button_class_init, + ephy_navigation_button_init, EPHY_TYPE_TBI); + +static void +ephy_navigation_button_class_init (EphyNavigationButtonClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = ephy_navigation_button_finalize_impl; + + EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_navigation_button_get_widget_impl; + EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_navigation_button_get_icon_impl; + EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_navigation_button_get_name_human_impl; + EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_navigation_button_to_string_impl; + EPHY_TB_ITEM_CLASS (klass)->clone = ephy_navigation_button_clone_impl; + EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_navigation_button_parse_properties_impl; + + ephy_tb_item_class = g_type_class_peek_parent (klass); +} + +static void +ephy_navigation_button_init (EphyNavigationButton *tbi) +{ + EphyNavigationButtonPrivate *p = g_new0 (EphyNavigationButtonPrivate, 1); + tbi->priv = p; + + p->direction = EPHY_NAVIGATION_DIRECTION_UP; + p->show_arrow = TRUE; + p->sensitive = TRUE; +} + +EphyNavigationButton * +ephy_navigation_button_new (void) +{ + EphyNavigationButton *ret = g_object_new (EPHY_TYPE_NAVIGATION_BUTTON, NULL); + return ret; +} + +static void +ephy_navigation_button_finalize_impl (GObject *o) +{ + EphyNavigationButton *it = EPHY_NAVIGATION_BUTTON (o); + EphyNavigationButtonPrivate *p = it->priv; + + if (p->widget) + { + g_object_unref (p->widget); + } + + g_free (p); + + DEBUG_MSG (("EphyNavigationButton finalized\n")); + + G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o); +} + +static void +ephy_navigation_button_setup_widget (EphyNavigationButton *b) +{ + EphyNavigationButtonPrivate *p = b->priv; + const gchar *label; + const gchar *tip; + gboolean prio; + + if (!p->widget) + { + ephy_navigation_button_get_widget_impl (EPHY_TB_ITEM (b)); + } + g_assert (EPHY_IS_TB_BUTTON (p->widget)); + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_UP: + label = "gtk-go-up"; + tip = _("Go up"); + prio = FALSE; + break; + case EPHY_NAVIGATION_DIRECTION_BACK: + label = "gtk-go-back"; + tip = _("Go back"); + prio = TRUE; + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + label = "gtk-go-forward"; + tip = _("Go forward"); + prio = FALSE; + break; + default: + g_assert_not_reached (); + label = NULL; + tip = NULL; + prio = FALSE; + break; + } + + ephy_tb_button_set_label (p->widget, label); + ephy_tb_button_set_tooltip_text (p->widget, tip); + ephy_tb_button_set_priority (p->widget, prio); + ephy_tb_button_set_show_arrow (p->widget, p->show_arrow); + ephy_tb_button_set_sensitivity (p->widget, p->sensitive); +} + +static GtkWidget * +ephy_navigation_button_get_widget_impl (EphyTbItem *i) +{ + EphyNavigationButton *iz = EPHY_NAVIGATION_BUTTON (i); + EphyNavigationButtonPrivate *p = iz->priv; + + if (!p->widget) + { + p->widget = ephy_tb_button_new (); + g_object_ref (p->widget); + ephy_tb_button_set_use_stock (p->widget, TRUE); + ephy_tb_button_set_enable_menu (p->widget, TRUE); + + ephy_navigation_button_setup_widget (iz); + + gtk_widget_show (GTK_WIDGET (p->widget)); + + g_signal_connect (p->widget, "menu-activated", + G_CALLBACK (ephy_navigation_button_menu_activated_cb), i); + g_signal_connect (ephy_tb_button_get_button (p->widget), "clicked", + G_CALLBACK (ephy_navigation_button_clicked_cb), i); + } + + return GTK_WIDGET (p->widget); +} + +static GdkPixbuf * +ephy_navigation_button_get_icon_impl (EphyTbItem *i) +{ + EphyNavigationButtonPrivate *p = EPHY_NAVIGATION_BUTTON (i)->priv; + + static GdkPixbuf *pb_up = NULL; + static GdkPixbuf *pb_back = NULL; + static GdkPixbuf *pb_forward = NULL; + + if (!pb_up) + { + /* what's the easier way? */ + GtkWidget *b = gtk_button_new (); + pb_up = gtk_widget_render_icon (b, + GTK_STOCK_GO_UP, + GTK_ICON_SIZE_SMALL_TOOLBAR, + NULL); + pb_back = gtk_widget_render_icon (b, + GTK_STOCK_GO_BACK, + GTK_ICON_SIZE_SMALL_TOOLBAR, + NULL); + pb_forward = gtk_widget_render_icon (b, + GTK_STOCK_GO_FORWARD, + GTK_ICON_SIZE_SMALL_TOOLBAR, + NULL); + gtk_widget_destroy (b); + } + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_BACK: + return g_object_ref (pb_back); + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + return g_object_ref (pb_forward); + break; + case EPHY_NAVIGATION_DIRECTION_UP: + return g_object_ref (pb_up); + break; + default: + g_assert_not_reached (); + return NULL; + } +} + +static gchar * +ephy_navigation_button_get_name_human_impl (EphyTbItem *i) +{ + EphyNavigationButtonPrivate *p = EPHY_NAVIGATION_BUTTON (i)->priv; + const gchar *ret; + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_BACK: + ret = p->show_arrow + ? _("Back (with menu)") + : _("Back"); + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + ret = p->show_arrow + ? _("Forward (with menu)") + : _("Forward"); + break; + case EPHY_NAVIGATION_DIRECTION_UP: + ret = p->show_arrow + ? _("Up (with menu)") + : _("Up"); + break; + default: + g_assert_not_reached (); + ret = "Error: unexpected direction"; + break; + } + + return g_strdup (ret); +} + +static gchar * +ephy_navigation_button_to_string_impl (EphyTbItem *i) +{ + EphyNavigationButtonPrivate *p = EPHY_NAVIGATION_BUTTON (i)->priv; + + /* if it had any properties, the string should include them */ + const char *sdir; + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_BACK: + sdir = "back"; + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + sdir = "forward"; + break; + case EPHY_NAVIGATION_DIRECTION_UP: + sdir = "up"; + break; + default: + g_assert_not_reached (); + sdir = "unknown"; + } + + return g_strdup_printf ("%s=navigation_button(direction=%s,arrow=%s)", + i->id, sdir, p->show_arrow ? "TRUE" : "FALSE"); +} + +static EphyTbItem * +ephy_navigation_button_clone_impl (EphyTbItem *i) +{ + EphyTbItem *ret = EPHY_TB_ITEM (ephy_navigation_button_new ()); + EphyNavigationButtonPrivate *p = EPHY_NAVIGATION_BUTTON (i)->priv; + + ephy_tb_item_set_id (ret, i->id); + + ephy_navigation_button_set_direction (EPHY_NAVIGATION_BUTTON (ret), p->direction); + ephy_navigation_button_set_show_arrow (EPHY_NAVIGATION_BUTTON (ret), p->show_arrow); + + return ret; +} + +static void +ephy_navigation_button_parse_properties_impl (EphyTbItem *it, const gchar *props) +{ + EphyNavigationButton *b = EPHY_NAVIGATION_BUTTON (it); + + /* we have two properties, the direction and the arrow */ + const gchar *direc_prop; + const gchar *show_arrow_prop; + + direc_prop = strstr (props, "direction="); + if (direc_prop) + { + direc_prop += strlen ("direction="); + if (!strncmp (direc_prop, "back", 4)) + { + ephy_navigation_button_set_direction (b, EPHY_NAVIGATION_DIRECTION_BACK); + } + else if (!strncmp (direc_prop, "forward", 4)) + { + ephy_navigation_button_set_direction (b, EPHY_NAVIGATION_DIRECTION_FORWARD); + } + else if (!strncmp (direc_prop, "up", 2)) + { + ephy_navigation_button_set_direction (b, EPHY_NAVIGATION_DIRECTION_UP); + } + } + + show_arrow_prop = strstr (props, "arrow="); + if (show_arrow_prop) + { + show_arrow_prop += strlen ("arrow="); + if (show_arrow_prop[0] == 'T') + { + ephy_navigation_button_set_show_arrow (b, TRUE); + } + else + { + ephy_navigation_button_set_show_arrow (b, FALSE); + } + } +} + + +void +ephy_navigation_button_set_direction (EphyNavigationButton *b, + EphyNavigationDirection d) +{ + EphyNavigationButtonPrivate *p = b->priv; + p->direction = d; + ephy_navigation_button_setup_widget (b); +} + +void +ephy_navigation_button_set_show_arrow (EphyNavigationButton *b, + gboolean value) +{ + EphyNavigationButtonPrivate *p = b->priv; + p->show_arrow = value; + if (p->widget) + { + ephy_tb_button_set_show_arrow (p->widget, p->show_arrow); + } + else + { + ephy_navigation_button_get_widget_impl (EPHY_TB_ITEM (b)); + } +} + +EphyNavigationDirection +ephy_navigation_button_get_direction (EphyNavigationButton *b) +{ + return b->priv->direction; +} + +void +ephy_navigation_button_set_sensitive (EphyNavigationButton *b, gboolean s) +{ + EphyNavigationButtonPrivate *p = b->priv; + p->sensitive = s; + if (p->widget) + { + ephy_tb_button_set_sensitivity (p->widget, s); + } + else + { + ephy_navigation_button_get_widget_impl (EPHY_TB_ITEM (b)); + } +} + +static void +ephy_navigation_button_clicked_cb (GtkWidget *w, EphyNavigationButton *b) +{ + EphyNavigationButtonPrivate *p = b->priv; + EphyWindow *window; + EphyEmbed *embed; + + window = ephy_tbi_get_window (EPHY_TBI (b)); + g_return_if_fail (window != NULL); + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (embed != NULL); + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_UP: + ephy_embed_go_up (embed); + break; + case EPHY_NAVIGATION_DIRECTION_BACK: + ephy_embed_go_back (embed); + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + ephy_embed_go_forward (embed); + break; + default: + g_assert_not_reached (); + break; + } +} + +/* TODO: clean all this, it came from toolbar.c and is messy */ + +static GtkWidget * +new_history_menu_item (gchar *origtext, + const GdkPixbuf *ico) +{ + GtkWidget *item = gtk_image_menu_item_new (); + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + GtkWidget *label = gtk_label_new (origtext); + + gtk_box_pack_start (GTK_BOX (hb), label, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (item), hb); + + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), + gtk_image_new_from_pixbuf ((GdkPixbuf *) ico)); + + gtk_widget_show_all (item); + + return item; +} + +static void +activate_back_or_forward_menu_item_cb (GtkWidget *menu, EphyWindow *window) +{ + EphyEmbed *embed; + int go_nth; + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (embed != NULL); + + go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth"); + + ephy_embed_shistory_go_nth (embed, go_nth); +} + +static void +activate_up_menu_item_cb (GtkWidget *menu, EphyWindow *window) +{ + EphyEmbed *embed; + int go_nth; + GSList *l; + gchar *url; + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (embed != NULL); + + go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth"); + + ephy_embed_get_go_up_list (embed, &l); + + url = g_slist_nth_data (l, go_nth); + if (url) + { + ephy_embed_load_url (embed, url); + } + + g_slist_foreach (l, (GFunc) g_free, NULL); + g_slist_free (l); +} + +static void +setup_back_or_forward_menu (EphyWindow *window, GtkMenuShell *ms, EphyNavigationDirection dir) +{ + int pos, count; + EphyEmbed *embed; + int start, end; + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (embed != NULL); + + ephy_embed_shistory_get_pos (embed, &pos); + ephy_embed_shistory_count (embed, &count); + + if (count == 0) return; + + if (dir == EPHY_NAVIGATION_DIRECTION_BACK) + { + start = pos - 1; + end = -1; + } + else + { + start = pos + 1; + end = count; + } + + while (start != end) + { + char *title, *url; + GtkWidget *item; + ephy_embed_shistory_get_nth (embed, start, FALSE, &url, &title); + item = new_history_menu_item (url, NULL); + gtk_menu_shell_append (ms, item); + g_object_set_data (G_OBJECT (item), "go_nth", GINT_TO_POINTER (start)); + g_signal_connect (item, "activate", + G_CALLBACK (activate_back_or_forward_menu_item_cb), window); + gtk_widget_show_all (item); + + g_free (url); + g_free (title); + + if (start < end) + { + start++; + } + else + { + start--; + } + } +} + +static void +setup_up_menu (EphyWindow *window, GtkMenuShell *ms) +{ + EphyEmbed *embed; + GSList *l; + GSList *li; + int count = 0; + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (embed != NULL); + + ephy_embed_get_go_up_list (embed, &l); + + for (li = l; li; li = li->next) + { + char *url = li->data; + GtkWidget *item; + + item = new_history_menu_item (url, NULL); + gtk_menu_shell_append (ms, item); + g_object_set_data (G_OBJECT(item), "go_nth", GINT_TO_POINTER (count)); + g_signal_connect (item, "activate", + G_CALLBACK (activate_up_menu_item_cb), window); + gtk_widget_show_all (item); + count ++; + } + + g_slist_foreach (l, (GFunc) g_free, NULL); + g_slist_free (l); +} + +static void +ephy_navigation_button_menu_activated_cb (EphyTbButton *w, EphyNavigationButton *b) +{ + EphyNavigationButtonPrivate *p = b->priv; + GtkMenuShell *ms = ephy_tb_button_get_menu (p->widget); + EphyWindow *win = ephy_tbi_get_window (EPHY_TBI (b)); + GList *children; + GList *li; + + children = gtk_container_get_children (GTK_CONTAINER (ms)); + for (li = children; li; li = li->next) + { + gtk_container_remove (GTK_CONTAINER (ms), li->data); + } + g_list_free (children); + + switch (p->direction) + { + case EPHY_NAVIGATION_DIRECTION_UP: + setup_up_menu (win, ms); + break; + case EPHY_NAVIGATION_DIRECTION_FORWARD: + case EPHY_NAVIGATION_DIRECTION_BACK: + setup_back_or_forward_menu (win, ms, p->direction); + break; + default: + g_assert_not_reached (); + break; + } +} diff --git a/src/ephy-navigation-button.h b/src/ephy-navigation-button.h new file mode 100644 index 000000000..036ec6d7e --- /dev/null +++ b/src/ephy-navigation-button.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_NAVIGATION_BUTTON_H +#define EPHY_NAVIGATION_BUTTON_H + +#include "ephy-tbi.h" + +G_BEGIN_DECLS + +/* object forward declarations */ + +typedef struct _EphyNavigationButton EphyNavigationButton; +typedef struct _EphyNavigationButtonClass EphyNavigationButtonClass; +typedef struct _EphyNavigationButtonPrivate EphyNavigationButtonPrivate; + +/** + * TbiZoom object + */ + +#define EPHY_TYPE_NAVIGATION_BUTTON (ephy_navigation_button_get_type()) +#define EPHY_NAVIGATION_BUTTON(object) (G_TYPE_CHECK_INSTANCE_CAST((object), \ + EPHY_TYPE_NAVIGATION_BUTTON, EphyNavigationButton)) +#define EPHY_NAVIGATION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_NAVIGATION_BUTTON,\ + EphyNavigationButtonClass)) +#define EPHY_IS_NAVIGATION_BUTTON(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), \ + EPHY_TYPE_NAVIGATION_BUTTON)) +#define EPHY_IS_NAVIGATION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_NAVIGATION_BUTTON)) +#define EPHY_NAVIGATION_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_NAVIGATION_BUTTON,\ + EphyNavigationButtonClass)) + +typedef enum +{ + EPHY_NAVIGATION_DIRECTION_UP, + EPHY_NAVIGATION_DIRECTION_BACK, + EPHY_NAVIGATION_DIRECTION_FORWARD +} EphyNavigationDirection; + +struct _EphyNavigationButtonClass +{ + EphyTbiClass parent_class; +}; + +/* Remember: fields are public read-only */ +struct _EphyNavigationButton +{ + EphyTbi parent_object; + EphyNavigationButtonPrivate *priv; +}; + +/* this class is abstract */ + +GType ephy_navigation_button_get_type (void); +EphyNavigationButton * ephy_navigation_button_new (void); +void ephy_navigation_button_set_direction (EphyNavigationButton *a, + EphyNavigationDirection d); +void ephy_navigation_button_set_show_arrow (EphyNavigationButton *b, + gboolean value); +EphyNavigationDirection ephy_navigation_button_get_direction (EphyNavigationButton *b); +void ephy_navigation_button_set_sensitive (EphyNavigationButton *b, gboolean s); + +G_END_DECLS + +#endif diff --git a/src/ephy-tbi.c b/src/ephy-tbi.c new file mode 100644 index 000000000..0c6e04f9b --- /dev/null +++ b/src/ephy-tbi.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <libgnome/gnome-i18n.h> +#include "ephy-gobject-misc.h" +#include "ephy-marshal.h" +#include "ephy-bonobo-extensions.h" +#include "ephy-tbi.h" +#include <string.h> + +#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC); +//#define DEBUG_MSG(x) g_print x +#define DEBUG_MSG(x) + +/** + * Private data + */ +struct _EphyTbiPrivate +{ +}; + +/** + * Private functions, only availble from this file + */ +static void ephy_tbi_class_init (EphyTbiClass *klass); +static void ephy_tbi_init (EphyTbi *tb); +static void ephy_tbi_finalize_impl (GObject *o); +static GtkWidget * ephy_tbi_get_widget_impl (EphyTbItem *i); +static GdkPixbuf * ephy_tbi_get_icon_impl (EphyTbItem *i); +static gchar * ephy_tbi_get_name_human_impl (EphyTbItem *i); +static gchar * ephy_tbi_to_string_impl (EphyTbItem *i); +static gboolean ephy_tbi_is_unique_impl (EphyTbItem *i); +static EphyTbItem * ephy_tbi_clone_impl (EphyTbItem *i); +static void ephy_tbi_parse_properties_impl (EphyTbItem *i, const gchar *props); +static void ephy_tbi_add_to_bonobo_tb_impl (EphyTbItem *i, + BonoboUIComponent *ui, + const char *container_path, + guint index); + + +static gpointer ephy_tb_item_class; + +/** + * EphyTbi object + */ + +MAKE_GET_TYPE (ephy_tbi, "EphyTbi", EphyTbi, ephy_tbi_class_init, + ephy_tbi_init, EPHY_TYPE_TB_ITEM); + +static void +ephy_tbi_class_init (EphyTbiClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = ephy_tbi_finalize_impl; + + EPHY_TB_ITEM_CLASS (klass)->get_widget = ephy_tbi_get_widget_impl; + EPHY_TB_ITEM_CLASS (klass)->get_icon = ephy_tbi_get_icon_impl; + EPHY_TB_ITEM_CLASS (klass)->get_name_human = ephy_tbi_get_name_human_impl; + EPHY_TB_ITEM_CLASS (klass)->to_string = ephy_tbi_to_string_impl; + EPHY_TB_ITEM_CLASS (klass)->is_unique = ephy_tbi_is_unique_impl; + EPHY_TB_ITEM_CLASS (klass)->clone = ephy_tbi_clone_impl; + EPHY_TB_ITEM_CLASS (klass)->parse_properties = ephy_tbi_parse_properties_impl; + EPHY_TB_ITEM_CLASS (klass)->add_to_bonobo_tb = ephy_tbi_add_to_bonobo_tb_impl; + + ephy_tb_item_class = g_type_class_peek_parent (klass); +} + +static void +ephy_tbi_init (EphyTbi *tbi) +{ + tbi->window = NULL; +} + +static void +ephy_tbi_finalize_impl (GObject *o) +{ + EphyTbi *it = EPHY_TBI (o); + + if (it->window) + { + g_object_remove_weak_pointer (G_OBJECT (it->window), + (gpointer *) &it->window); + } + + DEBUG_MSG (("EphyTbi finalized\n")); + + G_OBJECT_CLASS (ephy_tb_item_class)->finalize (o); +} + +static GtkWidget * +ephy_tbi_get_widget_impl (EphyTbItem *i) +{ + /* this class is abstract */ + g_assert_not_reached (); + + return NULL; +} + +static GdkPixbuf * +ephy_tbi_get_icon_impl (EphyTbItem *i) +{ + return NULL; +} + +static gchar * +ephy_tbi_get_name_human_impl (EphyTbItem *i) +{ + /* this class is abstract */ + g_assert_not_reached (); + + return NULL; +} + +static gchar * +ephy_tbi_to_string_impl (EphyTbItem *i) +{ + /* this class is abstract */ + g_assert_not_reached (); + + return NULL; +} + +static gboolean +ephy_tbi_is_unique_impl (EphyTbItem *i) +{ + return TRUE; +} + +static EphyTbItem * +ephy_tbi_clone_impl (EphyTbItem *i) +{ + /* you can't clone this directly because this class is abstract */ + g_assert_not_reached (); + return NULL; +} + +static void +ephy_tbi_add_to_bonobo_tb_impl (EphyTbItem *i, BonoboUIComponent *ui, + const char *container_path, guint index) +{ + GtkWidget *w = ephy_tb_item_get_widget (i); + gtk_widget_show (w); + ephy_bonobo_add_numbered_widget (ui, w, index, container_path); +} + +static void +ephy_tbi_parse_properties_impl (EphyTbItem *it, const gchar *props) +{ + /* we have no properties */ +} + +void +ephy_tbi_set_window (EphyTbi *it, EphyWindow *w) +{ + if (it->window) + { + g_object_remove_weak_pointer (G_OBJECT (it->window), + (gpointer *) &it->window); + } + + it->window = w; + + if (it->window) + { + g_object_add_weak_pointer (G_OBJECT (it->window), + (gpointer *) &it->window); + } +} + +EphyWindow * +ephy_tbi_get_window (EphyTbi *tbi) +{ + return tbi->window; +} + diff --git a/src/ephy-tbi.h b/src/ephy-tbi.h new file mode 100644 index 000000000..2296a144f --- /dev/null +++ b/src/ephy-tbi.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_TBI_H +#define EPHY_TBI_H + +#include "ephy-toolbar-item.h" +#include "ephy-window.h" + +G_BEGIN_DECLS + +/* object forward declarations */ + +typedef struct _EphyTbi EphyTbi; +typedef struct _EphyTbiClass EphyTbiClass; +typedef struct _EphyTbiPrivate EphyTbiPrivate; + +/** + * Tbi object + */ + +#define EPHY_TYPE_TBI (ephy_tbi_get_type()) +#define EPHY_TBI(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_TBI,\ + EphyTbi)) +#define EPHY_TBI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_TBI,\ + EphyTbiClass)) +#define EPHY_IS_TBI_(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_TBI)) +#define EPHY_IS_TBI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_TBI)) +#define EPHY_TBI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_TBI,\ + EphyTbiClass)) + +struct _EphyTbiClass +{ + EphyTbItemClass parent_class; + +}; + +/* Remember: fields are public read-only */ +struct _EphyTbi +{ + EphyTbItem parent_object; + + EphyWindow *window; +}; + +/* this class is abstract */ + +GType ephy_tbi_get_type (void); +EphyTbi * ephy_tbi_new (void); +void ephy_tbi_set_window (EphyTbi *tbi, EphyWindow *w); +EphyWindow * ephy_tbi_get_window (EphyTbi *tbi); + +G_END_DECLS + +#endif diff --git a/src/toolbar.c b/src/toolbar.c index 4bff4615e..059f1277d 100755 --- a/src/toolbar.c +++ b/src/toolbar.c @@ -32,8 +32,10 @@ #include "ephy-embed-favicon.h" #include "ephy-dnd.h" #include "ephy-toolbar-bonobo-view.h" +#include "ephy-toolbar-item-factory.h" #include "ephy-prefs.h" #include "eel-gconf-extensions.h" +#include "ephy-navigation-button.h" #include <string.h> #include <bonobo/bonobo-i18n.h> @@ -45,18 +47,13 @@ #include <gtk/gtkmenu.h> #define DEFAULT_TOOLBAR_SETUP \ - "back=std_toolitem(item=back);" \ - "back_history=navigation_history(direction=back);" \ - "up=std_toolitem(item=up);" \ - "up_history=navigation_history(direction=up);" \ - "forward=std_toolitem(item=forward);" \ - "forward_history=navigation_history(direction=forward);" \ + "back_menu=navigation_button(direction=back,arrow=TRUE);" \ + "forward_menu=navigation_button(direction=forward,arrow=TRUE);" \ "stop=std_toolitem(item=stop);" \ "reload=std_toolitem(item=reload);" \ "home=std_toolitem(item=home);" \ "favicon=favicon;" \ "location=location;" \ - "zoom=zoom;" \ "spinner=spinner;" #define ZOOM_DELAY 50 @@ -102,13 +99,8 @@ struct ToolbarPrivate GtkWidget *spinner; gboolean visibility; - /* This field is unused... what is it? - GdkPixbufAnimation *animation; - */ - GtkWidget *back_button; - GtkWidget *forward_button; - GtkWidget *up_button; GtkWidget *location_entry; + GSList *navigation_buttons; GtkTooltips *tooltips; GtkWidget *favicon; GtkWidget *favicon_ebox; @@ -165,6 +157,8 @@ toolbar_class_init (ToolbarClass *klass) "Parent window", EPHY_WINDOW_TYPE, G_PARAM_READWRITE)); + ephy_toolbar_item_register_type + ("navigation_button", (EphyTbItemConstructor) ephy_navigation_button_new); } static void @@ -177,9 +171,9 @@ toolbar_set_property (GObject *object, switch (prop_id) { - case PROP_EPHY_WINDOW: - toolbar_set_window (t, g_value_get_object (value)); - break; + case PROP_EPHY_WINDOW: + toolbar_set_window (t, g_value_get_object (value)); + break; } } @@ -199,247 +193,6 @@ toolbar_get_property (GObject *object, } } -static GtkWidget * -new_history_menu_item (gint num, gchar *origtext, gboolean lettersok, - GtkWidget *menu, const GdkPixbuf *ico) -{ - GtkWidget *item = gtk_image_menu_item_new (); - GtkWidget *hb = gtk_hbox_new (FALSE, 0); - GtkWidget *label = gtk_label_new (origtext); - - gtk_box_pack_start (GTK_BOX (hb), label, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER (item), hb); - - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), - gtk_image_new_from_pixbuf ((GdkPixbuf *) ico)); - - gtk_widget_show_all (item); - - return item; -} - -static void -activate_back_or_forward_menu_item_cb (GtkWidget *menu, EphyWindow *window) -{ - EphyEmbed *embed; - int go_nth; - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth"); - - ephy_embed_shistory_go_nth (embed, go_nth); -} - -static void -activate_up_menu_item_cb (GtkWidget *menu, EphyWindow *window) -{ - EphyEmbed *embed; - int go_nth; - GSList *l; - gchar *url; - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth"); - - ephy_embed_get_go_up_list (embed, &l); - - url = g_slist_nth_data (l, go_nth); - if (url) - { - ephy_embed_load_url (embed, url); - } - - g_slist_foreach (l, (GFunc) g_free, NULL); - g_slist_free (l); -} - -static gboolean -back_or_forward_button_pressed_callback (GtkWidget *widget, - GdkEventButton *event, - gpointer *user_data) -{ - Toolbar *t; - GtkWidget *menu; - int pos, count; - EphyEmbed *embed; - int start, end, accell_count = 0; - - g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE); - - t = TOOLBAR (user_data); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - - embed = ephy_window_get_active_embed (t->priv->window); - g_return_val_if_fail (embed != NULL, FALSE); - - ephy_embed_shistory_get_pos (embed, &pos); - ephy_embed_shistory_count (embed, &count); - - if (count == 0) return FALSE; - - if (widget == t->priv->back_button) - { - start = pos - 1; - end = -1; - } - else - { - start = pos + 1; - end = count; - } - - menu = gtk_menu_new (); - - while (start != end) - { - char *title, *url; - GtkWidget *item; - ephy_embed_shistory_get_nth (embed, start, FALSE, - &url, &title); - item = new_history_menu_item (accell_count, url, TRUE, - menu, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_object_set_data (G_OBJECT(item), "go_nth", GINT_TO_POINTER (start)); - g_signal_connect (item, "activate", - G_CALLBACK (activate_back_or_forward_menu_item_cb), - t->priv->window); - gtk_widget_show_all (item); - - g_free (url); - g_free (title); - - accell_count++; - if (start < end) start++; - else start--; - } - - - gnome_popup_menu_do_popup_modal (menu, - ephy_gui_menu_position_under_widget, widget, event, widget, widget); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); - - return TRUE; -} - -static gboolean -up_button_pressed_callback (GtkWidget *widget, - GdkEventButton *event, - gpointer *user_data) -{ - Toolbar *t; - GtkWidget *menu; - EphyEmbed *embed; - int accell_count = 0; - GSList *l; - GSList *li; - - g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE); - - t = TOOLBAR (user_data); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - - embed = ephy_window_get_active_embed (t->priv->window); - g_return_val_if_fail (embed != NULL, FALSE); - - ephy_embed_get_go_up_list (embed, &l); - - if (l == NULL) return FALSE; - - menu = gtk_menu_new (); - - for (li = l; li; li = li->next) - { - char *url = li->data; - GtkWidget *item; - item = new_history_menu_item (accell_count, url, TRUE, - menu, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_object_set_data (G_OBJECT(item), "go_nth", GINT_TO_POINTER (accell_count)); - g_signal_connect (item, "activate", - G_CALLBACK (activate_up_menu_item_cb), - t->priv->window); - gtk_widget_show_all (item); - - accell_count++; - } - - g_slist_foreach (l, (GFunc) g_free, NULL); - g_slist_free (l); - - gnome_popup_menu_do_popup_modal (menu, - ephy_gui_menu_position_under_widget, widget, event, widget, widget); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); - - return TRUE; -} - -static gboolean -back_or_forward_key_pressed_callback (GtkWidget *widget, - GdkEventKey *event, - gpointer *user_data) -{ - if (event->keyval == GDK_space || - event->keyval == GDK_KP_Space || - event->keyval == GDK_Return || - event->keyval == GDK_KP_Enter) - { - back_or_forward_button_pressed_callback (widget, NULL, user_data); - } - - return FALSE; -} - -static gboolean -up_key_pressed_callback (GtkWidget *widget, - GdkEventKey *event, - gpointer *user_data) -{ - if (event->keyval == GDK_space || - event->keyval == GDK_KP_Space || - event->keyval == GDK_Return || - event->keyval == GDK_KP_Enter) - { - up_button_pressed_callback (widget, NULL, user_data); - } - - return FALSE; -} - -static void -toolbar_setup_navigation_button (Toolbar *t, GtkWidget *w, const char *tooltip) -{ - g_signal_connect_object (w, "key_press_event", - G_CALLBACK (back_or_forward_key_pressed_callback), - t, 0); - g_signal_connect_object (w, "button_press_event", - G_CALLBACK (back_or_forward_button_pressed_callback), - t, 0); - - gtk_tooltips_set_tip (t->priv->tooltips, w, tooltip, NULL); -} - -static void -toolbar_setup_up_button (Toolbar *t, GtkWidget *w, const char *tooltip) -{ - g_signal_connect_object (w, "key_press_event", - G_CALLBACK (up_key_pressed_callback), - t, 0); - g_signal_connect_object (w, "button_press_event", - G_CALLBACK (up_button_pressed_callback), - t, 0); - - gtk_tooltips_set_tip (t->priv->tooltips, w, tooltip, NULL); -} - - static void toolbar_location_url_activate_cb (EphyLocationEntry *entry, const char *content, @@ -607,6 +360,9 @@ toolbar_get_widgets (Toolbar *t) ToolbarPrivate *p; EphyToolbar *gt; EphyTbItem *it; + GSList *li; + const gchar *nav_buttons_ids[] = {"back", "back_menu", "up", "up_menu", "forward", "forward_menu" }; + guint i; DEBUG_MSG (("in toolbar_get_widgets\n")); @@ -617,23 +373,12 @@ toolbar_get_widgets (Toolbar *t) /* release all the widgets */ - if (p->back_button) + for (li = p->navigation_buttons; li; li = li->next) { - g_object_unref (p->back_button); - p->back_button = NULL; - } - - if (p->forward_button) - { - g_object_unref (p->forward_button); - p->forward_button = NULL; - } - - if (p->up_button) - { - g_object_unref (p->up_button); - p->up_button = NULL; + g_object_unref (li->data); } + g_slist_free (p->navigation_buttons); + p->navigation_buttons = NULL; if (p->favicon_ebox) { @@ -667,34 +412,26 @@ toolbar_get_widgets (Toolbar *t) gt = EPHY_TOOLBAR (t); - it = ephy_toolbar_get_item_by_id (gt, "back_history"); - if (it) - { - p->back_button = ephy_tb_item_get_widget (it); - g_object_ref (p->back_button); - toolbar_setup_navigation_button (t, p->back_button, _("Go back a number of pages")); - - DEBUG_MSG ((" got a back_history button\n")); - } - - it = ephy_toolbar_get_item_by_id (gt, "forward_history"); - if (it) - { - p->forward_button = ephy_tb_item_get_widget (it); - g_object_ref (p->forward_button); - toolbar_setup_navigation_button (t, p->forward_button, _("Go forward a number of pages")); - - DEBUG_MSG ((" got a forward_history button\n")); - } - - it = ephy_toolbar_get_item_by_id (gt, "up_history"); - if (it) + for (i = 0; i < G_N_ELEMENTS (nav_buttons_ids); ++i) { - p->up_button = ephy_tb_item_get_widget (it); - g_object_ref (p->up_button); - toolbar_setup_up_button (t, p->up_button, _("Go up a number of levels")); - - DEBUG_MSG ((" got a up_history button\n")); + it = ephy_toolbar_get_item_by_id (gt, nav_buttons_ids[i]); + if (it) + { + if (EPHY_IS_NAVIGATION_BUTTON (it)) + { + DEBUG_MSG ((" got a navigation button\n")); + p->navigation_buttons = g_slist_prepend (p->navigation_buttons, g_object_ref (it)); + if (p->window) + { + ephy_tbi_set_window (EPHY_TBI (it), p->window); + } + } + else + { + g_warning ("An unexpected button has been found in your toolbar. " + "Maybe your setup is too old."); + } + } } it = ephy_toolbar_get_item_by_id (gt, "location"); @@ -748,6 +485,7 @@ toolbar_init (Toolbar *t) t->priv->window = NULL; t->priv->ui_component = NULL; + t->priv->navigation_buttons = NULL; t->priv->visibility = TRUE; t->priv->tooltips = gtk_tooltips_new (); g_object_ref (t->priv->tooltips); @@ -785,6 +523,7 @@ toolbar_finalize (GObject *object) { Toolbar *t; ToolbarPrivate *p; + GSList *li; g_return_if_fail (object != NULL); g_return_if_fail (IS_TOOLBAR (object)); @@ -795,9 +534,6 @@ toolbar_finalize (GObject *object) g_return_if_fail (p != NULL); if (p->location_entry) g_object_unref (p->location_entry); - if (p->back_button) g_object_unref (p->back_button); - if (p->forward_button) g_object_unref (p->forward_button); - if (p->up_button) g_object_unref (p->up_button); if (p->favicon_ebox) g_object_unref (p->favicon_ebox); if (p->favicon) g_object_unref (p->favicon); if (p->spinner) g_object_unref (p->spinner); @@ -808,6 +544,12 @@ toolbar_finalize (GObject *object) g_source_remove (p->zoom_timeout_id); } + for (li = t->priv->navigation_buttons; li; li = li->next) + { + g_object_unref (li->data); + } + g_slist_free (t->priv->navigation_buttons); + g_object_unref (t->priv->bview); g_free (t->priv); @@ -869,6 +611,22 @@ toolbar_spinner_stop (Toolbar *t) } } +static void +toolbar_navigation_button_set_sensitive (Toolbar *t, EphyNavigationDirection d, gboolean sensitivity) +{ + GSList *li; + ToolbarPrivate *p = t->priv; + + for (li = p->navigation_buttons; li; li = li->next) + { + EphyNavigationButton *b = EPHY_NAVIGATION_BUTTON (li->data); + if (ephy_navigation_button_get_direction (b) == d) + { + ephy_navigation_button_set_sensitive (b, sensitivity); + } + } +} + void toolbar_button_set_sensitive (Toolbar *t, ToolbarButtonID id, @@ -877,40 +635,19 @@ toolbar_button_set_sensitive (Toolbar *t, switch (id) { case TOOLBAR_BACK_BUTTON: - ephy_bonobo_set_sensitive (t->priv->ui_component, - "/commands/GoBack", - sensitivity); - if (t->priv->back_button) - { - gtk_widget_set_sensitive (t->priv->back_button, - sensitivity); - } + toolbar_navigation_button_set_sensitive (t, EPHY_NAVIGATION_DIRECTION_BACK, sensitivity); break; case TOOLBAR_FORWARD_BUTTON: - ephy_bonobo_set_sensitive (t->priv->ui_component, - "/commands/GoForward", - sensitivity); - if (t->priv->forward_button) - { - gtk_widget_set_sensitive (t->priv->forward_button, - sensitivity); - } + toolbar_navigation_button_set_sensitive (t, EPHY_NAVIGATION_DIRECTION_FORWARD, sensitivity); + break; + case TOOLBAR_UP_BUTTON: + toolbar_navigation_button_set_sensitive (t, EPHY_NAVIGATION_DIRECTION_UP, sensitivity); break; case TOOLBAR_STOP_BUTTON: ephy_bonobo_set_sensitive (t->priv->ui_component, "/commands/GoStop", sensitivity); break; - case TOOLBAR_UP_BUTTON: - ephy_bonobo_set_sensitive (t->priv->ui_component, - "/commands/GoUp", - sensitivity); - if (t->priv->up_button) - { - gtk_widget_set_sensitive (t->priv->up_button, - sensitivity); - } - break; } } diff --git a/src/window-commands.c b/src/window-commands.c index cef1d675c..c7d5ec16c 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -41,13 +41,12 @@ #include <gtk/gtkeditable.h> #define AVAILABLE_TOOLBAR_ITEMS \ - "new=std_toolitem(item=new);" \ - "back=std_toolitem(item=back);" \ - "back_history=navigation_history(direction=back);" \ - "up=std_toolitem(item=up);" \ - "up_history=navigation_history(direction=up);" \ - "forward=std_toolitem(item=forward);" \ - "forward_history=navigation_history(direction=forward);" \ + "back=navigation_button(direction=back,arrow=FALSE);" \ + "back_menu=navigation_button(direction=back,arrow=TRUE);" \ + "forward=navigation_button(direction=forward,arrow=FALSE);" \ + "forward_menu=navigation_button(direction=forward,arrow=TRUE);" \ + "up=navigation_button(direction=up,arrow=FALSE);" \ + "up_menu=navigation_button(direction=up,arrow=TRUE);" \ "stop=std_toolitem(item=stop);" \ "reload=std_toolitem(item=reload);" \ "home=std_toolitem(item=home);" \ @@ -58,8 +57,6 @@ "spinner=spinner;" \ "separator;" - - void window_cmd_edit_find (BonoboUIComponent *uic, EphyWindow *window, |