Initial, incomplete, version of lookuplet.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@35 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2000-12-10 23:38:39 +00:00
parent d15f6917bd
commit 537e308c62
20 changed files with 929 additions and 0 deletions
+192
View File
@@ -0,0 +1,192 @@
/**
* $Id: launcher.c,v 1.1 2000/12/10 23:38:39 mdb Exp $
*/
#include <string.h>
#include <ctype.h>
#include <config.h>
#include <glib.h>
#include <gnome.h>
#include "launcher.h"
#define DEFAULT_QUERY "http://search.metacrawler.com/crawler?general=%U"
/**
* This hashtable stores the mappings from qualifier keys to URL templates
* for use when we launch a URL for a particular set of terms.
*/
static GHashTable* _qualmap;
/**
* Removes and frees any previous entry registered with the supplied key
* before inserting the new key/value pair.
*/
static void
g_hash_table_insert_safe (GHashTable* table, gchar* key, gchar* value)
{
gpointer oldkey, oldvalue;
if (g_hash_table_lookup_extended(table, key, &oldkey, &oldvalue)) {
g_free(oldkey);
g_free(oldvalue);
}
g_hash_table_insert(table, key, value);
}
/**
* Loads up the mappings for the launcher from the configuration
* repository.
*/
void
lookuplet_launcher_init (void)
{
_qualmap = g_hash_table_new(g_str_hash, g_str_equal);
/* for now, just insert some bogus config parameters */
g_hash_table_insert_safe(_qualmap,
g_strdup("Ctrl-s"), g_strdup(DEFAULT_QUERY));
}
static void
free_table_entry (gpointer key, gpointer value, gpointer rock)
{
g_free(key);
g_free(value);
}
/**
* Frees the mapping information used by the launcher.
*/
void
lookuplet_launcher_cleanup (void)
{
g_hash_table_foreach(_qualmap, free_table_entry, NULL);
g_hash_table_destroy(_qualmap);
_qualmap = NULL;
}
#define ESC_CHAR '%'
static const gchar*
escape (gchar value)
{
static char buffer[] = "%xx";
static char* xlate = "0123456789ABCDEF";
buffer[0] = ESC_CHAR;
buffer[1] = xlate[(value >> 4) & 0xF];
buffer[2] = xlate[value & 0xF];
return buffer;
}
/**
* URL encodes the supplied text. The result must be freed by the caller
* using g_free().
*/
static gchar*
url_encode (const gchar* text)
{
GString* result;
guint tlen, i;
gchar* retval;
tlen = strlen(text);
result = g_string_sized_new(tlen);
for (i = 0; i < tlen; i++) {
if (!isalnum(text[i]) || text[i] == ESC_CHAR) {
g_string_append(result, escape(text[i]));
} else {
g_string_append_c(result, text[i]);
}
}
retval = result->str;
g_string_free(result, FALSE);
return retval;
}
/**
* Replaces all instances of before with after in the supplied source
* string.
*
* @return the number of replacements made.
*/
static
guint g_string_replace (GString* source, const gchar* before,
const gchar* after)
{
gchar* pos;
gchar* spot;
guint beflen = strlen(before);
guint aftlen = strlen(after);
guint replacements = 0;
/* sanity checks */
g_return_val_if_fail(source != NULL, 0);
g_return_val_if_fail(before != NULL, 0);
g_return_val_if_fail(after != NULL, 0);
g_return_val_if_fail(beflen > 0, 0);
pos = source->str;
while ((spot = strstr(pos, before)) != NULL) {
replacements++;
/* erase the match and insert the new stuff */
g_string_erase(source, spot-source->str, beflen);
g_string_insert(source, spot-source->str, after);
/* move the pointer on up */
pos += spot-source->str + aftlen;
}
return replacements;
}
#define TOKEN_START '%'
#define TERM_TOKEN 'T'
#define ENCODED_TERM_TOKEN "U"
/**
* Displays a URL with the supplied terms appropriately embedded. The URL
* shown depends on the supplied qualifier. Each qualifier is mapped to a
* particular URL into which the terms are substituted before loading.
*
* @return false if no qualifier mapping could be found for the supplied
* qualifier.
*/
gboolean
lookuplet_launcher_launch (const char* terms, const char* qualifier)
{
gchar* uterms;
gchar* template;
uterms = url_encode(terms);
/* if no qualifier was supplied, we use the default template;
* otherwise we get the template from the mapping table */
if (qualifier == NULL) {
template = DEFAULT_QUERY;
} else {
template = g_hash_table_lookup(_qualmap, qualifier);
}
/* if we found a template, construct the actual URL from it by
* replacing instances of %T with the terms and %U with the URL
* encoded terms. */
if (template != NULL) {
GString* url = g_string_new(template);
/* first replace %U because we know that won't result in any '%T's
* being inserted into the string because the url encoded terms
* encode all %s */
g_string_replace(url, "%U", uterms);
g_string_replace(url, "%T", terms);
gnome_url_show(url->str);
g_string_free(url, TRUE);
}
g_free(uterms);
return TRUE;
}
+19
View File
@@ -0,0 +1,19 @@
/**
* $Id: launcher.h,v 1.1 2000/12/10 23:38:39 mdb Exp $
*/
#ifndef _LAUNCHER_H_
#define _LAUNCHER_H_
#include <glib.h>
extern void
lookuplet_launcher_init (void);
extern void
lookuplet_launcher_cleanup (void);
extern gboolean
lookuplet_launcher_launch (const char* terms, const char* qualifier);
#endif /* _LAUNCHER_H_ */
+41
View File
@@ -0,0 +1,41 @@
/**
* $Id: lookuplet.c,v 1.1 2000/12/10 23:38:39 mdb Exp $
*/
#include <config.h>
#include <gnome.h>
#include <applet-widget.h>
#include "querybox.h"
int
main (int argc, char** argv)
{
GtkWidget* applet;
GtkWidget* contents;
/* initialize the i18n stuff */
bindtextdomain(PACKAGE, GNOMELOCALEDIR);
textdomain(PACKAGE);
/* intialize, this will basically set up the applet, corba and
call gnome_init */
applet_widget_init("lookuplet", NULL, argc, argv, NULL, 0, NULL);
/* create a new applet_widget */
applet = applet_widget_new("lookuplet");
if (applet == NULL) {
g_error("Can't create applet!\n");
}
/* create our contents and set them up real proper like */
contents = lookuplet_querybox_create();
applet_widget_add(APPLET_WIDGET(applet), contents);
gtk_widget_show(contents);
gtk_widget_show(applet);
/* special corba main loop */
applet_widget_gtk_main();
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
/**
* $Id: querybox.c,v 1.1 2000/12/10 23:38:39 mdb Exp $
*/
#include <config.h>
#include <glib.h>
#include <gnome.h>
#include "launcher.h"
#include "querybox.h"
#define BORDER 1
#define SPACER 2
static void
launch (GtkWidget* widget, gpointer data)
{
gchar* search_text = gtk_entry_get_text(GTK_ENTRY(widget));
/* pass the contents of the querybox on to the launcher for display
* (specifying NULL for the qualifier since they just pressed return
* instead of pressing some special key combination) */
lookuplet_launcher_launch(search_text, NULL);
/* clear out the contents of the entry box */
gtk_entry_set_text(GTK_ENTRY(widget), "");
}
GtkWidget*
lookuplet_querybox_create ()
{
GtkWidget* vbox;
GtkWidget* label;
GtkWidget* query;
/* create the widget we are going to put on the applet */
label = gtk_label_new(_("Query"));
gtk_widget_show(label);
/* make the query text box and attach the "activate" signal handler */
query = gtk_entry_new();
/* Connect "return" in the search box to the launch func. */
gtk_signal_connect(GTK_OBJECT(query), "activate",
GTK_SIGNAL_FUNC(launch), NULL);
/* create a vertical box to hold our query input box and the label */
vbox = gtk_hbox_new(FALSE, SPACER);
/* pack the query box and label into the vbox */
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, SPACER);
gtk_box_pack_start(GTK_BOX(vbox), query, FALSE, FALSE, SPACER);
gtk_widget_show(query);
gtk_widget_show(label);
return vbox;
}
+11
View File
@@ -0,0 +1,11 @@
/**
* $Id: querybox.h,v 1.1 2000/12/10 23:38:39 mdb Exp $
*/
#ifndef _QUERYBOX_H_
#define _QUERYBOX_H_
extern GtkWidget*
lookuplet_querybox_create (void);
#endif /* _QUERYBOX_H_ */