[PATCH] keyboard accelerators for bookmarks

Juho Snellman <[email protected]>
Newsgroups gmane.comp.web.galeon.devel
Message-ID <[email protected]>
Attached patch adds support for using any keyboard accelerator
information that's found in the bookmark files. There's no UI for
adding/modifying accelerators, so as for now it's mainly good for
maintaining galeon1 compability. Adding UI support beyond "type a text
representation of the shortcut into a text entry field" is beyond my
meagre GTK skills. (Too bad that bonobo-ui menus don't seem to support
gtk-can-change-accels). 

The patch also resurrects the galeon1 behaviour on selecting a smart
bookmark from a menu/with a keyboard shortcut. A dialog with a text
entry widget is popped up, and any text entered there is treated the
same way as text entered into the corresponding field in the 
smart bookmark toolbar.

If needed, I can supply separate patches for the above items.

-- 
Juho Snellman
galeon-bookmark-accel-2003-04-01.patch (text/plain, 21.1 KB)
diff -ur --new-file clean.galeon/bookmarks/bookmarks.c galeon/bookmarks/bookmarks.c
--- clean.galeon/bookmarks/bookmarks.c	2003-04-01 21:43:51.000000000 +0300
+++ galeon/bookmarks/bookmarks.c	2003-04-01 22:05:11.000000000 +0300
@@ -32,6 +32,7 @@
 #include "gul-gobject-misc.h"
 #include <string.h>
 #include "galeon-autocompletion-source.h"
+#include "bonobo/bonobo-ui-util.h"
 
 #define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
 
@@ -909,6 +910,8 @@
 {
 	g_free (c->url);
 	c->url = g_strdup (b->url);
+	g_free (c->accel_name);
+	c->accel_name = g_strdup (b->accel_name);
 	c->accel_key = b->accel_key;
 	c->accel_mods = b->accel_mods;
 	c->time_visited = b->time_visited;
@@ -970,6 +973,8 @@
 
 	g_free (alias->url);
 	alias->url = s->url;
+	g_free (alias->url);
+	alias->accel_name = s->accel_name;
 	alias->accel_key = s->accel_key;
 	alias->accel_mods = s->accel_mods;
 	alias->time_visited = s->time_visited;
@@ -1039,15 +1044,28 @@
 void
 gb_site_set_accel (GbSite *b, guint accel_key, guint accel_mods)
 {
+        gchar *accel_name = NULL;
+        GbBookmarkSet *set;
+        
 	g_return_if_fail (GB_IS_BOOKMARK (b));
 	
 	b = GB_SITE (gb_bookmark_real_bookmark ((GbBookmark *) b));
-
+        
+        accel_name = bonobo_ui_util_accel_name(accel_key, accel_mods);
+        set = GB_BOOKMARK(b)->set;
+        
+        if (set != NULL && accel_name != NULL) {
+                g_hash_table_insert (set->accel_to_bookmark, accel_name, b);
+        }
+        
+        g_free(b->accel_name);
+        
 	gb_bookmark_set_needs_saving (b);
 
 	do {
-		b->accel_mods = accel_mods;
-		b->accel_key = accel_key;
+                b->accel_name = accel_name;
+                b->accel_key = accel_key;
+                b->accel_mods = accel_mods;
 		g_signal_emit (b, GbBookmarkSignals[GB_BOOKMARK_MODIFIED], 0);
 		gb_folder_emit_child_modified (((GbBookmark *)b)->parent, (GbBookmark *) b);
 	} while ((b = (GbSite *) ((GbBookmark *) b)->alias) != NULL);
@@ -2437,6 +2455,7 @@
 	b->default_folder = b->root;
 	b->id_to_bookmark = g_hash_table_new (NULL, NULL);
 	b->url_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
+	b->accel_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
 #ifdef NICK_HASHTABLE
 	b->nick_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
 #endif
@@ -2500,6 +2519,7 @@
 		    g_hash_table_size (set->url_to_bookmark), 
 		    g_hash_table_size (set->id_to_bookmark)));
 
+	g_hash_table_destroy (set->accel_to_bookmark);
 	g_hash_table_destroy (set->url_to_bookmark);
 #ifdef NICK_HASHTABLE
 	g_hash_table_destroy (set->nick_to_bookmark);
@@ -2791,6 +2811,13 @@
 	return g_hash_table_lookup (set->url_to_bookmark, url);
 }
 
+GbBookmark *
+gb_bookmark_set_get_bookmark_by_accel (GbBookmarkSet *set,
+                                       const gchar *accel_name)
+{
+	return g_hash_table_lookup (set->accel_to_bookmark, accel_name);
+}
+
 static GbBookmark *
 gb_bookmark_set_get_bookmark_by_nick_rec (GbFolder *root, 
 					  const gchar *nick)
diff -ur --new-file clean.galeon/bookmarks/bookmarks.h galeon/bookmarks/bookmarks.h
--- clean.galeon/bookmarks/bookmarks.h	2003-04-01 21:43:51.000000000 +0300
+++ galeon/bookmarks/bookmarks.h	2003-04-01 19:09:14.000000000 +0300
@@ -183,6 +183,7 @@
 	/* accel data */
 	guint accel_key;
 	guint accel_mods;
+        gchar *accel_name;
 
 	/* time info */
 	GTime time_visited;
@@ -442,6 +443,7 @@
 
 	GHashTable *id_to_bookmark;
 	GHashTable *url_to_bookmark;
+	GHashTable *accel_to_bookmark;
 
 	GSList *unresolved_aliases;
 
@@ -475,6 +477,8 @@
 void		gb_bookmark_set_fix_galeon1_mess (GbBookmarkSet *set);
 GbBookmark *	gb_bookmark_set_get_bookmark_by_url (GbBookmarkSet *set, 
 						     const gchar *url);
+GbBookmark *	gb_bookmark_set_get_bookmark_by_accel (GbBookmarkSet *set, 
+                                                       const gchar *accel_name);
 GbBookmark *	gb_bookmark_set_get_bookmark_by_nick (GbBookmarkSet *set, 
 						      const gchar *nick);
 gchar *		gb_bookmark_set_get_url_by_nick_and_args (GbBookmarkSet *set, 
diff -ur --new-file clean.galeon/bookmarks/xbel.c galeon/bookmarks/xbel.c
--- clean.galeon/bookmarks/xbel.c	2003-04-01 21:43:52.000000000 +0300
+++ galeon/bookmarks/xbel.c	2003-04-01 22:06:14.000000000 +0300
@@ -726,9 +726,11 @@
 		md->smart_site_history = gb_smart_site_get_history (GB_SMART_SITE (b), 0);
 	}
 	md->t_vis = b->time_visited;
+        
+        
 	md->acc_mod = b->accel_mods;
-	md->acc_key = b->accel_key;
-
+	md->acc_key = b->accel_key;        
+        
 	xbel_save_galeon_metadata (newNode, md);
 	gb_xbel_metadata_free (md);
 
diff -ur --new-file clean.galeon/src/galeon-window.c galeon/src/galeon-window.c
--- clean.galeon/src/galeon-window.c	2003-04-01 21:43:54.000000000 +0300
+++ galeon/src/galeon-window.c	2003-04-01 21:50:46.000000000 +0300
@@ -35,6 +35,7 @@
 #include "galeon-shell.h"
 #include "bookmarks-bonoboui-menu.h"
 #include "bookmarks-bonoboui-tb.h"
+#include "bookmarks-util.h"
 #include "gul-bonobo-extensions.h"
 #include "eel-gconf-extensions.h"
 #include "prefs-strings.h"
@@ -43,6 +44,7 @@
 #include "bookmarks-editor-dockable.h"
 #include "window-recent-history-menu.h"
 #include "galeon-embed-prefs.h"
+#include "smart-bookmark-dialog.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -220,6 +222,10 @@
 void /* yes, this is not static */
 galeon_window_bookmark_activate (GaleonWindow *w, GbBookmarkEventActivated *ev);
 
+void
+static galeon_window_show_smart_bookmark_dialog (GaleonWindow *window, 
+                                                 GbSmartSite *bookmark);
+
 static char *
 galeon_window_gb_location_source_get_location (GbLocationSource *src);
 static char *
@@ -276,6 +282,9 @@
 				  GdkEventKey *event,
 				  GaleonWindow *window)
 {
+	GbBookmarkSet *bs;
+        GbSite *s;
+        gchar *accel_name;
         int page;
 
 	if ((event->state & GDK_Shift_L) || (event->state & GDK_Shift_R))
@@ -296,6 +305,23 @@
                 }
         }
 	
+        accel_name = bonobo_ui_util_accel_name(event->keyval, event->state);
+        
+        bs = galeon_shell_get_bookmark_set (galeon_shell);
+        s = GB_SITE (gb_bookmark_set_get_bookmark_by_accel (bs, accel_name));
+        g_free(accel_name);
+        
+        if (s != NULL) {
+                GbBookmarkEventActivated event = { GB_BOOKMARK (s), 
+                                                   s->url, GB_BAF_DEFAULT, 
+                                                   NULL};
+                galeon_window_bookmark_activate ( GALEON_WINDOW (widget), 
+                                                  &event );
+                /* galeon_window_load_url ( GALEON_WINDOW (widget), s->url); */
+                return TRUE;
+        }
+        
+        
         return FALSE;
 }
 
@@ -1981,7 +2023,17 @@
 
 	if (GB_IS_SITE (b) && f == GB_BAF_DEFAULT)
 	{
-		galeon_window_load_url (w, url);
+                if (GB_IS_SMART_SITE (b) && 
+                    /* The smart bookmark url being the same as the
+                     * event url implies that the user selected the
+                     * bookmark from a menu or using a keyboard shortcut.
+                     */
+                    strcmp(GB_SMART_SITE(b)->smarturl, url) == 0)
+                {
+                        galeon_window_show_smart_bookmark_dialog (w, GB_SMART_SITE(b));
+                } else {
+                        galeon_window_load_url (w, url);
+                }
 		return;
 	}
 
@@ -2146,6 +2198,14 @@
 }
 
 void
+static galeon_window_show_smart_bookmark_dialog (GaleonWindow *window, 
+                                                 GbSmartSite *bookmark)
+{			       
+        GaleonDialog *dialog = smart_bookmark_dialog_new (window, bookmark);
+	galeon_dialog_show (dialog);        
+}
+
+void
 galeon_window_show_history (GaleonWindow *window)
 {
 	GaleonEmbed *embed;
diff -ur --new-file clean.galeon/src/Makefile.am galeon/src/Makefile.am
--- clean.galeon/src/Makefile.am	2003-04-01 21:43:53.000000000 +0300
+++ galeon/src/Makefile.am	2003-03-31 23:28:59.000000000 +0300
@@ -87,6 +87,8 @@
 	network-prefs.h					\
 	pdm-dialog.c					\
 	pdm-dialog.h					\
+	smart-bookmark-dialog.c				\
+	smart-bookmark-dialog.h				\
 	galeon-bookmarks-icon-provider.h 		\
 	galeon-bookmarks-icon-provider.c		\
 	window-recent-history.h				\
diff -ur --new-file clean.galeon/src/smart-bookmark-dialog.c galeon/src/smart-bookmark-dialog.c
--- clean.galeon/src/smart-bookmark-dialog.c	1970-01-01 02:00:00.000000000 +0200
+++ galeon/src/smart-bookmark-dialog.c	2003-04-01 13:06:57.000000000 +0300
@@ -0,0 +1,172 @@
+/*
+ *  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.
+ */
+
+#include "smart-bookmark-dialog.h"
+#include "galeon-shell.h"
+#include "bookmarks.h"
+#include "gtk/gtkentry.h"
+#include "gtk/gtklabel.h"
+#include "gtk/gtkbutton.h"
+
+static GObjectClass *parent_class = NULL;
+
+static void
+smart_bookmark_dialog_class_init (SmartBookmarkDialogClass *klass);
+static void
+smart_bookmark_dialog_init (SmartBookmarkDialog *dialog);
+static void
+smart_bookmark_dialog_finalize (GObject *object);
+
+void
+smart_bookmark_dialog_ok_cb (GtkButton *button, 
+                             SmartBookmarkDialog *dialog);
+void
+smart_bookmark_dialog_cancel_cb (GtkButton *button, 
+                                 SmartBookmarkDialog *dialog);
+
+enum
+{
+        PROP_BOOKMARK_NAME,
+        PROP_BOOKMARK_DATA,
+        PROP_OK_BUTTON,
+        PROP_CANCEL_BUTTON
+};
+
+static const
+GaleonDialogProperty properties [] =
+{ 
+        { PROP_BOOKMARK_NAME, "bookmark_name_label", NULL, PT_NORMAL, NULL },
+	{ PROP_BOOKMARK_DATA, "bookmark_data_entry", NULL, PT_NORMAL, NULL },
+	{ PROP_OK_BUTTON,     "ok_button", NULL, PT_NORMAL, NULL },
+	{ PROP_CANCEL_BUTTON, "cancel_button", NULL, PT_NORMAL, NULL },
+
+	{ -1, NULL, NULL }
+};
+
+GType 
+smart_bookmark_dialog_get_type (void)
+{
+        static GType smart_bookmark_dialog_type = 0;
+
+        if (smart_bookmark_dialog_type == 0)
+        {
+                static const GTypeInfo our_info =
+                {
+                        sizeof (SmartBookmarkDialogClass),
+                        NULL, /* base_init */
+                        NULL, /* base_finalize */
+                        (GClassInitFunc) smart_bookmark_dialog_class_init,
+                        NULL,
+                        NULL, /* class_data */
+                        sizeof (SmartBookmarkDialog),
+                        0, /* n_preallocs */
+                        (GInstanceInitFunc) smart_bookmark_dialog_init
+                };
+
+                smart_bookmark_dialog_type = g_type_register_static (GALEON_DIALOG_TYPE,
+                                                                     "SmartBookmarkDialog",
+                                                                     &our_info, 0);
+        }
+
+        return smart_bookmark_dialog_type;
+}
+
+static void
+smart_bookmark_dialog_class_init (SmartBookmarkDialogClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        
+        parent_class = g_type_class_peek_parent (klass);
+        
+        object_class->finalize = smart_bookmark_dialog_finalize;
+}
+
+static void
+smart_bookmark_dialog_finalize (GObject *object)
+{
+        G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+smart_bookmark_dialog_set_bookmark (SmartBookmarkDialog *dialog, 
+                                    GbSmartSite *bookmark)
+{
+        GtkLabel *name_label;
+        
+        dialog->bookmark = bookmark;
+        
+        name_label = GTK_LABEL(galeon_dialog_get_control(GALEON_DIALOG(dialog), 
+                                                         PROP_BOOKMARK_NAME));
+        
+        gtk_label_set_text(name_label, GB_BOOKMARK(bookmark)->name);
+}
+
+GaleonDialog *
+smart_bookmark_dialog_new (GaleonWindow *parent, GbSmartSite *bookmark)
+{
+        GaleonDialog *dialog;
+        
+        dialog = GALEON_DIALOG (g_object_new (SMART_BOOKMARK_DIALOG_TYPE, 
+                                              NULL));
+        
+        SMART_BOOKMARK_DIALOG (dialog)->window = parent;
+        smart_bookmark_dialog_set_bookmark (SMART_BOOKMARK_DIALOG (dialog), 
+                                            bookmark);
+        
+        return dialog;        
+}
+
+static void
+smart_bookmark_dialog_init (SmartBookmarkDialog *dialog)
+{               
+	galeon_dialog_construct (GALEON_DIALOG(dialog),
+                                 properties,
+                                 "galeon.glade", 
+                                 "smart_bookmark_dialog");
+}
+
+static const gchar*
+smart_bookmark_dialog_get_url (SmartBookmarkDialog *dialog) 
+{
+        GtkEntry *data_entry = GTK_ENTRY(galeon_dialog_get_control(GALEON_DIALOG(dialog),
+                                                                   PROP_BOOKMARK_DATA));
+        return gtk_entry_get_text(data_entry);
+}
+
+void
+smart_bookmark_dialog_ok_cb (GtkButton *button, 
+                             SmartBookmarkDialog *dialog) 
+{
+        const gchar *arg = smart_bookmark_dialog_get_url(dialog);
+        const gchar *args[] = { arg, NULL };
+        const gchar *url = gb_smart_site_subst_args(dialog->bookmark, args);
+        
+        printf("url=%s\n", url);
+                
+        galeon_window_load_url(dialog->window, url);
+        
+	galeon_dialog_destruct (GALEON_DIALOG (dialog));
+        g_object_unref (dialog);        
+        g_free(url);
+}
+
+void
+smart_bookmark_dialog_cancel_cb (GtkButton *button, 
+                                 SmartBookmarkDialog *dialog) {
+	galeon_dialog_destruct (GALEON_DIALOG (dialog));
+	g_object_unref (dialog);
+}
diff -ur --new-file clean.galeon/src/smart-bookmark-dialog.h galeon/src/smart-bookmark-dialog.h
--- clean.galeon/src/smart-bookmark-dialog.h	1970-01-01 02:00:00.000000000 +0200
+++ galeon/src/smart-bookmark-dialog.h	2003-04-01 00:33:36.000000000 +0300
@@ -0,0 +1,54 @@
+/*
+ *  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 SMART_BOOKMARK_DIALOG_H
+#define SMART_BOOKMARK_DIALOG_H
+
+#include <galeon-dialog.h>
+#include <glib-object.h>
+#include <glib.h>
+
+#include "bookmarks.h"
+#include "galeon-window.h"
+
+typedef struct SmartBookmarkDialog SmartBookmarkDialog;
+typedef struct SmartBookmarkDialogClass SmartBookmarkDialogClass;
+
+#define SMART_BOOKMARK_DIALOG_TYPE             (smart_bookmark_dialog_get_type ())
+#define SMART_BOOKMARK_DIALOG(obj)             (GTK_CHECK_CAST ((obj), SMART_BOOKMARK_DIALOG_TYPE, SmartBookmarkDialog))
+#define SMART_BOOKMARK_DIALOG_CLASS(klass)     (GTK_CHECK_CLASS_CAST ((klass), SMART_BOOKMARK_DIALOG, SmartBookmarkDialogClass))
+#define IS_SMART_BOOKMARK_DIALOG(obj)          (GTK_CHECK_TYPE ((obj), SMART_BOOKMARK_DIALOG_TYPE))
+#define IS_SMART_BOOKMARK_DIALOG_CLASS(klass)  (GTK_CHECK_CLASS_TYPE ((klass), SMART_BOOKMARK_DIALOG))
+
+typedef struct SmartBookmarkDialogPrivate SmartBookmarkDialogPrivate;
+
+struct SmartBookmarkDialog
+{
+        GaleonDialog parent;        
+        GbSmartSite  *bookmark;
+        GaleonWindow *window;
+};
+
+struct SmartBookmarkDialogClass
+{
+        GaleonDialogClass parent_class;
+};
+
+GType             smart_bookmark_dialog_get_type          (void);
+GaleonDialog     *smart_bookmark_dialog_new               (GaleonWindow *parent,
+                                                           GbSmartSite *bookmark);
+
+#endif
diff -ur --new-file clean.galeon/ui/galeon.glade galeon/ui/galeon.glade
--- clean.galeon/ui/galeon.glade	2003-04-01 21:44:02.000000000 +0300
+++ galeon/ui/galeon.glade	2003-04-01 13:38:16.000000000 +0300
@@ -4060,4 +4060,118 @@
   </child>
 </widget>
 
+<widget class="GtkDialog" id="smart_bookmark_dialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Galeon smart bookmark</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox29">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area29">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="smart_bookmark_dialog_cancel_cb" last_modification_time="Mon, 31 Mar 2003 20:53:24 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="smart_bookmark_dialog_ok_cb" last_modification_time="Mon, 31 Mar 2003 20:52:43 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox137">
+	  <property name="border_width">6</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="bookmark_name_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">BOOKMARK_NAME</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">6</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkEntry" id="bookmark_data_entry">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="has_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">True</property>
+	      <property name="max_length">0</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="invisible_char" translatable="yes">*</property>
+	      <property name="activates_default">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">2</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.