998d8d60cb
git-svn-id: https://samskivert.googlecode.com/svn/trunk@309 6335cc39-0255-0410-8fd6-9bcaacd3b74c
229 lines
6.9 KiB
C
229 lines
6.9 KiB
C
/**
|
|
* $Id: querybox.c,v 1.8 2001/08/21 18:46:10 mdb Exp $
|
|
*
|
|
* lookuplet - a utility for quickly looking up information
|
|
* Copyright (C) 2001 Michael Bayne
|
|
*
|
|
* 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.1 of the License, 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 <config.h>
|
|
#include <glib.h>
|
|
#include <gnome.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
#include "binding.h"
|
|
#include "launcher.h"
|
|
#include "keysym-util.h"
|
|
#include "preferences.h"
|
|
#include "lookuplet.h"
|
|
#include "querybox.h"
|
|
|
|
static GtkWidget* _query;
|
|
|
|
/* used by url_p */
|
|
#define MATCH_PREFIX(text, prefix) !strncmp(text, prefix, sizeof(prefix)-1)
|
|
|
|
/**
|
|
* A very primitive function to try to determine if the selection is a URL
|
|
* of some sort.
|
|
*/
|
|
static int
|
|
url_p (const char* text)
|
|
{
|
|
return (MATCH_PREFIX(text, "http://") ||
|
|
MATCH_PREFIX(text, "ftp://") ||
|
|
MATCH_PREFIX(text, "https://") ||
|
|
MATCH_PREFIX(text, "file:/"));
|
|
}
|
|
|
|
static void
|
|
selection_received (GtkWidget* widget, GtkSelectionData* selection_data,
|
|
gpointer data)
|
|
{
|
|
int length = selection_data->length;
|
|
int is_url;
|
|
|
|
/* make sure some selection was provided */
|
|
if (length > 0) {
|
|
gchar* start, *end, *pos;
|
|
gchar* search_text =
|
|
gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
|
|
|
|
/* prune spaces from the end of the text */
|
|
for (start = search_text; isspace(*start); start++);
|
|
for (end = search_text + length - 1; isspace(*end); end--);
|
|
end++; *end = '\0';
|
|
|
|
/* check to see if we're looking at a url here */
|
|
is_url = url_p(start);
|
|
|
|
/* do some whitespace processing */
|
|
for (pos = start; *pos != '\0'; pos++) {
|
|
/* convert newlines to spaces */
|
|
if ((*pos == '\n') || (*pos == '\r')) {
|
|
*pos = ' ';
|
|
}
|
|
/* if this is a URL, we want to eat whitespace */
|
|
if (*pos == ' ' && is_url) {
|
|
memmove(pos, pos+1, strlen(pos));
|
|
}
|
|
}
|
|
|
|
/* only set the new text if we changed anything */
|
|
if (length != strlen(start)) {
|
|
length = strlen(start);
|
|
gtk_entry_set_text(GTK_ENTRY(widget), start);
|
|
}
|
|
g_free(search_text);
|
|
|
|
/* select the text in the entry so that it can be easily replaced */
|
|
gtk_editable_select_region(GTK_EDITABLE(_query), 0, length);
|
|
}
|
|
}
|
|
|
|
static gint
|
|
key_pressed (GtkWidget* widget, GdkEvent* event, gpointer callback_data)
|
|
{
|
|
GdkEventKey* ek = (GdkEventKey*)event;
|
|
GPtrArray* bindings;
|
|
gint handled = FALSE, i;
|
|
gchar* keystr;
|
|
|
|
/* ignore plain or shifted keystrokes */
|
|
if (ek->state <= 1) {
|
|
return FALSE;
|
|
}
|
|
|
|
/* otherwise convert the key combo to a name and look it up */
|
|
keystr = convert_keysym_state_to_string(ek->keyval, ek->state);
|
|
bindings = lk_prefs_get_bindings();
|
|
|
|
for (i = 0; i < bindings->len; i++) {
|
|
LkBinding* binding = LK_BINDING(g_ptr_array_index(bindings, i));
|
|
if (!strcmp(keystr, binding->key)) {
|
|
/* get the terms from the query box */
|
|
gchar* search_text =
|
|
gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
|
|
/* launch the appropriate thing */
|
|
lk_launcher_launch(binding, search_text);
|
|
g_free(search_text);
|
|
if (applet_mode) {
|
|
/* clear out the contents of the entry box */
|
|
gtk_entry_set_text(GTK_ENTRY(widget), "");
|
|
} else {
|
|
gtk_exit(0);
|
|
}
|
|
handled = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_free(keystr);
|
|
|
|
return handled;
|
|
}
|
|
|
|
static void
|
|
prefs_clicked (GtkWidget* widget, gpointer data)
|
|
{
|
|
lk_prefs_display();
|
|
}
|
|
|
|
static void
|
|
launch (GtkWidget* widget, gpointer data)
|
|
{
|
|
/* 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) */
|
|
gchar* search_text = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
|
|
lk_launcher_launch(NULL, search_text);
|
|
g_free(search_text);
|
|
|
|
if (applet_mode) {
|
|
/* clear out the contents of the entry box */
|
|
gtk_entry_set_text(GTK_ENTRY(widget), "");
|
|
} else {
|
|
gtk_exit(0);
|
|
}
|
|
}
|
|
|
|
GtkWidget*
|
|
lk_querybox_create (void)
|
|
{
|
|
GtkWidget* hbox;
|
|
GtkWidget* label;
|
|
GtkWidget* prefs;
|
|
|
|
/* create the widget we are going to put on the applet */
|
|
label = gtk_label_new(_("Query"));
|
|
|
|
/* 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 horizontal box to hold our query input box and the
|
|
* label */
|
|
hbox = gtk_hbox_new(FALSE, GNOME_PAD_SMALL);
|
|
|
|
/* pack the query box and label into the hbox */
|
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox), _query, TRUE, TRUE, 0);
|
|
|
|
/* create our preferences button (only if we're not an applet, if
|
|
* we're an applet we'll have a preferences menu item instead) */
|
|
if (!applet_mode) {
|
|
prefs = gtk_button_new_with_label(_("Prefs"));
|
|
gtk_signal_connect (GTK_OBJECT(prefs), "clicked",
|
|
GTK_SIGNAL_FUNC(prefs_clicked), NULL);
|
|
gtk_box_pack_start(GTK_BOX(hbox), prefs, FALSE, FALSE, 0);
|
|
}
|
|
|
|
return hbox;
|
|
}
|
|
|
|
void
|
|
lk_querybox_init (void)
|
|
{
|
|
static GdkAtom targets_atom = GDK_NONE;
|
|
|
|
/* wire up our key press event handler */
|
|
gtk_signal_connect(GTK_OBJECT(_query), "key_press_event",
|
|
GTK_SIGNAL_FUNC(key_pressed), NULL);
|
|
|
|
/* if we're not an applet, we want to request focus and grab the
|
|
current X selection */
|
|
if (!applet_mode) {
|
|
/* focus the text entry box */
|
|
gtk_widget_grab_focus(_query);
|
|
|
|
/* register a signal handler that will select the selection when
|
|
it arrives */
|
|
gtk_signal_connect_after(GTK_OBJECT(_query), "selection_received",
|
|
GTK_SIGNAL_FUNC(selection_received), NULL);
|
|
|
|
/* request the selection as type "STRING" */
|
|
if (targets_atom == GDK_NONE) {
|
|
targets_atom = gdk_atom_intern ("STRING", FALSE);
|
|
}
|
|
gtk_selection_convert(_query, GDK_SELECTION_PRIMARY, targets_atom,
|
|
GDK_CURRENT_TIME);
|
|
}
|
|
}
|