aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjasper@unix.geek.nz <jasper@unix.geek.nz@767c508d-d83b-0410-8cff-fd39cd899a2f>2008-03-26 07:07:15 +0000
committerjasper@unix.geek.nz <jasper@unix.geek.nz@767c508d-d83b-0410-8cff-fd39cd899a2f>2008-03-26 07:07:15 +0000
commitf71692e87f1e4b6786fe44f3665998a08ba9e761 (patch)
treec66ca122b0901ab0106396fe1a7521a40628a837
parentb1a96420ccdafd5e4d7327bf9e48fcb4897be355 (diff)
downloadjuniper-browser-f71692e87f1e4b6786fe44f3665998a08ba9e761.tar.gz
juniper-browser-f71692e87f1e4b6786fe44f3665998a08ba9e761.tar.bz2
juniper-browser-f71692e87f1e4b6786fe44f3665998a08ba9e761.zip
* Working bookmarks and prefs implementations using SQLite
* Tab title truncation * Less optimisations by default, makes it easier to make debug builds * Pass glade object around rather than individual elements from it
-rwxr-xr-xbuild.sh7
-rw-r--r--juniper.glade3
-rw-r--r--src/juniper-bookmarks.c130
-rw-r--r--src/juniper-bookmarks.h4
-rw-r--r--src/juniper-db.c17
-rw-r--r--src/juniper-db.h10
-rw-r--r--src/juniper-prefs.c65
-rw-r--r--src/juniper-prefs.h5
-rw-r--r--src/juniper-tabs.c33
-rw-r--r--src/juniper-tabs.h4
-rw-r--r--src/juniper-ui.c2
-rw-r--r--src/juniper-util.c30
-rw-r--r--src/juniper-util.h1
-rw-r--r--src/juniper.c7
14 files changed, 244 insertions, 74 deletions
diff --git a/build.sh b/build.sh
index 3101026..505374a 100755
--- a/build.sh
+++ b/build.sh
@@ -1,9 +1,9 @@
#!/bin/sh
set -e
-COMMON="-march=native -O2 -maccumulate-outgoing-args -s -pipe -Wall -pedantic -Werror $@"
+COMMON="-pipe -Wall -pedantic -Werror $@"
-DEPENDENCIES="libglade-2.0 gtk+-2.0 gtksourceview-1.0 webkit-1.0"
+DEPENDENCIES="libglade-2.0 gtk+-2.0 gtksourceview-1.0 webkit-1.0 sqlite3"
CFLAGS="$COMMON $(pkg-config --cflags $DEPENDENCIES)"
LDFLAGS="$COMMON -Wl,-E -Wl,--sort-common -Wl,--as-needed -Wl,--no-add-needed -Wl,--enable-new-dtags -Wl,--fatal-warnings"
@@ -19,6 +19,7 @@ cd src
gcc $CFLAGS -c juniper.c -o ../juniper.o
gcc $CFLAGS -c juniper-bookmarks.c -o ../juniper-bookmarks.o
+gcc $CFLAGS -c juniper-db.c -o ../juniper-db.o
gcc $CFLAGS -c juniper-events.c -o ../juniper-events.o
gcc $CFLAGS -c juniper-extensions.c -o ../juniper-extensions.o
gcc $CFLAGS -c juniper-fs.c -o ../juniper-fs.o
@@ -31,7 +32,7 @@ gcc $CFLAGS -c juniper-view-source.c -o ../juniper-view-source.o
cd ..
# Build dynamically-linked Juniper executable
-gcc $LDFLAGS -o juniper juniper.o juniper-bookmarks.o juniper-events.o juniper-extensions.o juniper-fs.o juniper-prefs.o juniper-tabs.o juniper-ui.o juniper-util.o juniper-view-source.o $LIBS
+gcc $LDFLAGS -o juniper juniper.o juniper-bookmarks.o juniper-db.o juniper-events.o juniper-extensions.o juniper-fs.o juniper-prefs.o juniper-tabs.o juniper-ui.o juniper-util.o juniper-view-source.o $LIBS
rm -f *.o
diff --git a/juniper.glade b/juniper.glade
index 9219c65..3b905fa 100644
--- a/juniper.glade
+++ b/juniper.glade
@@ -300,7 +300,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
- <signal name="activate" handler="juniper_bookmarks_cancel_add_bookmark_activate"/>
</widget>
</child>
<child>
@@ -312,7 +311,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-add</property>
<property name="use_stock">True</property>
- <property name="response_id">0</property>
+ <property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
diff --git a/src/juniper-bookmarks.c b/src/juniper-bookmarks.c
index 1556c26..20b2b8a 100644
--- a/src/juniper-bookmarks.c
+++ b/src/juniper-bookmarks.c
@@ -1,66 +1,144 @@
-#include "juniper-prefs.h"
+#include "juniper-bookmarks.h"
#include "assert.h"
#include "string.h"
+#include "sqlite3.h"
+#include "juniper-db.h"
#include "juniper-fs.h"
#include "juniper-tabs.h"
-#define BOOKMARKS_FILE "bookmarks.xml"
-
-static GBookmarkFile * bookmarks;
static GladeXML * glade;
+static GtkContainer * bookmarks_menu;
+
+static sqlite3 * db_handle;
+
+#define BOOKMARKS_MENU_POS 2
+#define NUM_MENUS 4
gboolean juniper_bookmarks_init(GladeXML * xml)
{
- GError * error = NULL;
- GtkMenu * bookmarks_menu;
-
glade = xml;
+ bookmarks_menu = GTK_CONTAINER(glade_xml_get_widget(glade, "bookmarks_menu"));
+
+ db_handle = juniper_db_get_handle();
+ assert(db_handle != NULL);
- bookmarks_menu = GTK_MENU(glade_xml_get_widget(xml, "bookmarks_menu"));
+ sqlite3_exec(db_handle, "create table bookmarks (uri varchar(255) not null unique, name varchar (255) not null)", NULL, NULL, NULL);
- bookmarks = g_bookmark_file_new();
- g_bookmark_file_load_from_file(bookmarks, juniper_fs_build_filename(BOOKMARKS_FILE), &error);
+ juniper_bookmarks_reload();
return true;
}
+void juniper_bookmarks_reload()
+{
+ sqlite3_stmt * statement;
+ GList * menu_item;
+ GtkWidget * bookmark, * separator;
+ const gchar * name;
+ gchar * uri;
+ gboolean first;
+
+#ifdef DEBUG
+ puts("reloading bookmarks");
+#endif
+
+ menu_item = gtk_container_get_children(bookmarks_menu);
+
+ while ((menu_item = g_list_next(menu_item)) != NULL)
+ gtk_container_remove(bookmarks_menu, GTK_WIDGET(menu_item->data));
+
+ sqlite3_prepare_v2(db_handle, "select name, uri from bookmarks order by name", -1, &statement, NULL);
+
+ first = true;
+ while (sqlite3_step(statement) == SQLITE_ROW)
+ {
+ if (first)
+ {
+ separator = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(bookmarks_menu), separator);
+ gtk_widget_show(separator);
+ first = false;
+ }
+
+ name = g_strdup((gchar *) sqlite3_column_text(statement, 0));
+ uri = g_strdup((gchar *) sqlite3_column_text(statement, 1));
+
+ bookmark = gtk_menu_item_new_with_label(name);
+ g_signal_connect(bookmark, "activate", G_CALLBACK(juniper_bookmarks_menu_item_activate), uri);
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(bookmarks_menu), bookmark);
+ gtk_widget_show(bookmark);
+
+#ifdef DEBUG
+ printf("bookmark added: name=%s, uri=%s\n", name, uri);
+#endif
+ }
+
+ sqlite3_finalize(statement);
+
+#ifdef DEBUG
+ puts("done reloading bookmarks");
+#endif
+}
+
void juniper_bookmarks_add_bookmark_menu_item_activate(GtkMenuItem * menu_item)
{
GtkDialog * add_bookmark_dialog;
GtkVBox * tab;
+ GtkEntry * name_entry, * url_entry;
+ const gchar * name, * url;
add_bookmark_dialog = GTK_DIALOG(glade_xml_get_widget(glade, "add_bookmark_dialog"));
tab = juniper_tabs_current();
- gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(glade, "name_entry")), juniper_tabs_get_title(tab));
- gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(glade, "url_entry")), gtk_entry_get_text(juniper_tabs_address_bar_for_tab(tab)));
+ name_entry = GTK_ENTRY(glade_xml_get_widget(glade, "name_entry"));
+ url_entry = GTK_ENTRY(glade_xml_get_widget(glade, "url_entry"));
+
+ gtk_entry_set_text(name_entry, juniper_tabs_get_title(tab));
+ gtk_entry_set_text(url_entry, gtk_entry_get_text(juniper_tabs_address_bar_for_tab(tab)));
+
+ if (gtk_dialog_run(add_bookmark_dialog) == 1)
+ {
+ name = gtk_entry_get_text(name_entry);
+ url = gtk_entry_get_text(url_entry);
+
+ if (NULL == name || NULL == url || strlen(name) == 0 || strlen(url) == 0)
+ return;
+
+ juniper_bookmarks_add(url, name);
+ }
- gtk_dialog_run(add_bookmark_dialog);
gtk_widget_hide(GTK_WIDGET(add_bookmark_dialog));
}
-void juniper_bookmarks_menu_item_activate(GtkMenuItem * menu_item, gchar * url)
+void juniper_bookmarks_menu_item_activate(GtkMenuItem * menu_item, const gchar * url)
{
juniper_tabs_add_with_location(url);
}
-gchar ** juniper_bookmarks_get_uris(gsize *length)
+void juniper_bookmarks_add(const gchar * uri, const gchar * name)
{
- return g_bookmark_file_get_uris(bookmarks, length);
-}
+ sqlite3_stmt * statement;
+ int result;
-gchar * juniper_bookmarks_get_title_for_uri(const gchar * uri)
-{
- GError * error;
+#ifdef DEBUG
+ printf("adding bookmark: %s (%s)\n", name, uri);
+#endif
- return g_bookmark_file_get_title(bookmarks, uri, &error);
-}
+ sqlite3_prepare_v2(db_handle, "insert into bookmarks (name, uri) values (?, ?)", -1, &statement, NULL);
+ sqlite3_bind_text(statement, 1, name, strlen(name), SQLITE_STATIC);
+ sqlite3_bind_text(statement, 2, uri, strlen(uri), SQLITE_STATIC);
-gchar * juniper_bookmarks_get_description_for_uri(const gchar * uri)
-{
- GError * error = NULL;
+ result = sqlite3_step(statement);
+
+#ifdef DEBUG
+ if (result != SQLITE_DONE)
+ printf("got strange sqlite result: %i (errmsg: %s)\n", result, sqlite3_errmsg(db_handle));
+#endif
+
+ sqlite3_finalize(statement);
- return g_bookmark_file_get_description(bookmarks, uri, &error);
+ juniper_bookmarks_reload();
}
diff --git a/src/juniper-bookmarks.h b/src/juniper-bookmarks.h
index ba4e1cd..044d813 100644
--- a/src/juniper-bookmarks.h
+++ b/src/juniper-bookmarks.h
@@ -5,8 +5,10 @@
#include "gtk/gtk.h"
gboolean juniper_bookmarks_init(GladeXML *);
+void juniper_bookmarks_reload();
void juniper_bookmarks_add_bookmark_menu_item_activate(GtkMenuItem * menu_item);
+void juniper_bookmarks_menu_item_activate(GtkMenuItem * menu_item, const gchar * uri);
gchar * juniper_bookmarks_get(gchar * title);
-void juniper_bookmarks_add(gchar * title, gchar * url);
+void juniper_bookmarks_add(const gchar * uri, const gchar * name);
#endif
diff --git a/src/juniper-db.c b/src/juniper-db.c
new file mode 100644
index 0000000..6f30202
--- /dev/null
+++ b/src/juniper-db.c
@@ -0,0 +1,17 @@
+#include "juniper-db.h"
+
+#include "juniper-fs.h"
+
+#define DB_FILE "juniper.db"
+
+static sqlite3 * db_handle;
+
+gboolean juniper_db_init()
+{
+ return (sqlite3_open(juniper_fs_build_filename(DB_FILE), &db_handle) == SQLITE_OK);
+}
+
+sqlite3 * juniper_db_get_handle()
+{
+ return db_handle;
+}
diff --git a/src/juniper-db.h b/src/juniper-db.h
new file mode 100644
index 0000000..feeb800
--- /dev/null
+++ b/src/juniper-db.h
@@ -0,0 +1,10 @@
+#ifndef JUNIPER_DB
+#define JUNIPER_DB
+
+#include "glib.h"
+#include "sqlite3.h"
+
+gboolean juniper_db_init();
+sqlite3 * juniper_db_get_handle();
+
+#endif
diff --git a/src/juniper-prefs.c b/src/juniper-prefs.c
index 3766851..74b4e4c 100644
--- a/src/juniper-prefs.c
+++ b/src/juniper-prefs.c
@@ -2,55 +2,52 @@
#include "assert.h"
#include "string.h"
-#include "libxml/parser.h"
-#include "libxml/tree.h"
+#include "sqlite3.h"
+#include "juniper-db.h"
#include "juniper-fs.h"
-#define PREFS_FILE "preferences.xml"
-
-static GHashTable * prefs_table = NULL;
+static sqlite3 * db_handle;
gboolean juniper_prefs_init()
{
- xmlDoc * doc = NULL;
- xmlNode * root_element = NULL;
- xmlNode * prefs_element = NULL;
-
- LIBXML_TEST_VERSION
+ db_handle = juniper_db_get_handle();
+ assert(db_handle != NULL);
- doc = xmlReadFile(juniper_fs_build_filename(PREFS_FILE), NULL, 0);
+ sqlite3_exec(db_handle, "create table preferences (key varchar(255) not null unique, value varchar (255) not null)", NULL, NULL, NULL);
+ return TRUE;
+}
- if (doc == NULL)
- {
- puts("Error reading preferences file");
- return FALSE;
- }
+const gchar * juniper_prefs_get(const gchar * key)
+{
+ sqlite3_stmt * statement;
+ gchar * value;
- root_element = xmlDocGetRootElement(doc);
+ sqlite3_prepare_v2(db_handle, "select key, value from preferences where key=?", -1, &statement, NULL);
+ sqlite3_bind_text(statement, 1, key, strlen(key), SQLITE_STATIC);
- prefs_table = g_hash_table_new(g_str_hash, g_str_equal);
+ if (sqlite3_step(statement) != SQLITE_ROW)
+ return NULL;
- for (prefs_element = root_element->children; prefs_element; prefs_element = prefs_element->next)
- {
- if (prefs_element->type == XML_ELEMENT_NODE)
- {
- g_hash_table_insert(prefs_table, (gchar *) prefs_element->name, prefs_element->content);
- }
- }
+ value = g_strdup((gchar *) sqlite3_column_text(statement, 1));
- xmlFreeDoc(doc);
- xmlCleanupParser();
+ sqlite3_finalize(statement);
- return TRUE;
+ return value;
}
-gpointer juniper_prefs_get(const gchar * key)
+gboolean juniper_prefs_set(const gchar * key, const gchar * value)
{
- return g_hash_table_lookup(prefs_table, key);
-}
+ sqlite3_stmt * statement;
-void juniper_prefs_set(const gchar * key, const gpointer value)
-{
- g_hash_table_insert(prefs_table, g_strdup(key), value);
+ sqlite3_prepare_v2(db_handle, "insert into preferences (key, value) values(?, ?)", -1, &statement, NULL);
+ sqlite3_bind_text(statement, 1, key, strlen(key), SQLITE_STATIC);
+ sqlite3_bind_text(statement, 2, value, strlen(value), SQLITE_STATIC);
+
+ if (sqlite3_step(statement) != SQLITE_DONE)
+ return FALSE;
+
+ sqlite3_finalize(statement);
+
+ return TRUE;
}
diff --git a/src/juniper-prefs.h b/src/juniper-prefs.h
index f71012d..aa1b59b 100644
--- a/src/juniper-prefs.h
+++ b/src/juniper-prefs.h
@@ -4,8 +4,7 @@
#include "gtk/gtk.h"
gboolean juniper_prefs_init();
-
-gpointer juniper_prefs_get(const gchar * key);
-void juniper_prefs_set(const gchar * key, const gpointer value);
+const gchar * juniper_prefs_get(const gchar * key);
+gboolean juniper_prefs_set(const gchar * key, const gchar * value);
#endif
diff --git a/src/juniper-tabs.c b/src/juniper-tabs.c
index 851d920..598a362 100644
--- a/src/juniper-tabs.c
+++ b/src/juniper-tabs.c
@@ -7,6 +7,9 @@
#include "juniper-events.h"
#include "juniper-prefs.h"
#include "juniper-ui.h"
+#include "juniper-util.h"
+
+#include "webkit/webkitwebframe.h"
#define MAX_TAB_COUNT 100
@@ -51,7 +54,7 @@ GtkVBox * juniper_tabs_nth(guint index)
const gchar * juniper_tabs_get_title(GtkVBox * tab)
{
- return gtk_label_get_text(GTK_LABEL(gtk_notebook_get_tab_label(tabs, GTK_WIDGET(tab))));
+ return webkit_web_frame_get_title(webkit_web_view_get_main_frame(juniper_tabs_page_for_tab(tab)));
}
void juniper_tabs_set_title(GtkVBox * tab, const gchar * title)
@@ -59,7 +62,7 @@ void juniper_tabs_set_title(GtkVBox * tab, const gchar * title)
GtkLabel * label;
label = GTK_LABEL(gtk_notebook_get_tab_label(tabs, GTK_WIDGET(tab)));
- gtk_label_set_text(label, title);
+ gtk_label_set_text(label, juniper_util_truncate(title, 24));
if (tab == juniper_tabs_current())
{
@@ -114,6 +117,8 @@ void juniper_tabs_close_current()
/* remove the tab from the notebook */
gtk_notebook_remove_page(tabs, gtk_notebook_get_current_page(tabs));
+
+ juniper_tabs_count_changed();
}
void juniper_tabs_next()
@@ -208,6 +213,30 @@ void juniper_tabs_add_with_location(const gchar * location)
{
gtk_label_set_text(label, "blank");
}
+
+ juniper_tabs_count_changed();
+}
+
+void juniper_tabs_count_changed()
+{
+ if (juniper_tabs_count() < 2)
+ {
+ juniper_tabs_hide();
+ }
+ else
+ {
+ juniper_tabs_show();
+ }
+}
+
+void juniper_tabs_hide()
+{
+ gtk_notebook_set_show_tabs(tabs, false);
+}
+
+void juniper_tabs_show()
+{
+ gtk_notebook_set_show_tabs(tabs, true);
}
void juniper_tabs_add()
diff --git a/src/juniper-tabs.h b/src/juniper-tabs.h
index bb23e7c..82d2862 100644
--- a/src/juniper-tabs.h
+++ b/src/juniper-tabs.h
@@ -25,4 +25,8 @@ void juniper_tabs_add();
void juniper_tabs_add_with_location(const gchar *);
void juniper_tabs_next();
+void juniper_tabs_count_changed();
+void juniper_tabs_show();
+void juniper_tabs_hide();
+
#endif
diff --git a/src/juniper-ui.c b/src/juniper-ui.c
index 1e9ac90..0803acf 100644
--- a/src/juniper-ui.c
+++ b/src/juniper-ui.c
@@ -32,7 +32,7 @@ void juniper_ui_set_window_title(const gchar * title)
{
gchar * new_title;
- if (strlen(title) < 1)
+ if (NULL == title || strlen(title) < 1)
new_title = "Juniper";
else
new_title = juniper_util_sprintf("%s - Juniper", title);
diff --git a/src/juniper-util.c b/src/juniper-util.c
index fd044d0..5d38899 100644
--- a/src/juniper-util.c
+++ b/src/juniper-util.c
@@ -6,6 +6,7 @@
#define SPRINTF_MAX_STRLEN 4096
#define MAX_URL_LENGTH 4000
+#define TRUNCATE_APPEND "…"
gchar * juniper_util_sprintf(const gchar * format_str, ...)
{
@@ -46,3 +47,32 @@ gchar * juniper_util_normalise_url(const gchar * url)
else
return g_strdup(url);
}
+
+gchar * juniper_util_truncate(const gchar * string, guint max_length)
+{
+ gchar * truncated;
+ int string_length, total_length;
+ gboolean truncate;
+
+ truncate = (strlen(string) > max_length);
+
+ if (truncate)
+ {
+ string_length = max_length + 1;
+ total_length = string_length + strlen(TRUNCATE_APPEND);
+ }
+ else
+ {
+ string_length = strlen(string) + 1;
+ total_length = string_length;
+ }
+
+ truncated = malloc(total_length);
+ strncpy(truncated, string, max_length);
+ truncated[string_length - 1] = '\0';
+
+ if (truncate)
+ strcat(truncated, TRUNCATE_APPEND);
+
+ return truncated;
+}
diff --git a/src/juniper-util.h b/src/juniper-util.h
index 9274f9e..e8b6fd1 100644
--- a/src/juniper-util.h
+++ b/src/juniper-util.h
@@ -5,5 +5,6 @@
gchar * juniper_util_sprintf(const gchar * format_str, ...);
gchar * juniper_util_normalise_url(const gchar * url);
+gchar * juniper_util_truncate(const gchar * string, guint max_length);
#endif
diff --git a/src/juniper.c b/src/juniper.c
index 48cb717..66f487d 100644
--- a/src/juniper.c
+++ b/src/juniper.c
@@ -3,6 +3,7 @@
#include "gtk/gtk.h"
#include "glade/glade.h"
+#include "juniper-db.h"
#include "juniper-events.h"
#include "juniper-tabs.h"
#include "juniper-view-source.h"
@@ -20,13 +21,15 @@ void juniper_quit()
int main(int argc, char **argv)
{
GladeXML * xml;
- gchar * url;
+ const gchar * url;
gtk_init(&argc, &argv);
+ g_set_application_name("Juniper");
+
xml = glade_xml_new("/usr/share/juniper/juniper.glade", NULL, NULL);
glade_xml_signal_autoconnect(xml);
- if (!(juniper_prefs_init() && juniper_bookmarks_init(xml) && juniper_ui_init(xml) && juniper_tabs_init(xml)))
+ if (!(juniper_db_init() && juniper_prefs_init() && juniper_bookmarks_init(xml) && juniper_ui_init(xml) && juniper_tabs_init(xml)))
return 1;
url = (argc == 2) ? argv[1] : juniper_prefs_get("homepage");