ayttm-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Ayttm-commits] CVS: ayttm/src/gtk gtkspell.c,NONE,1.1 gtkspell.h,NONE,1


From: Colin Leroy <address@hidden>
Subject: [Ayttm-commits] CVS: ayttm/src/gtk gtkspell.c,NONE,1.1 gtkspell.h,NONE,1.1 gtkutils.c,NONE,1.1 gtkutils.h,NONE,1.1 Makefile.am,1.1,1.2
Date: Tue, 28 Jan 2003 03:08:57 -0500

Update of /cvsroot/ayttm/ayttm/src/gtk
In directory subversions:/tmp/cvs-serv10765/src/gtk

Modified Files:
        Makefile.am 
Added Files:
        gtkspell.c gtkspell.h gtkutils.c gtkutils.h 
Log Message:
src/gtkspell.[ch] src/gtkutils.[ch]
moved to gtk/


--- NEW FILE: gtkspell.c ---
/* gtkspell - a spell-checking addon for GtkText
 * Copyright (c) 2000 Evan Martin.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 */

#include "intl.h"
#include <gtk/gtk.h>
#include <glib.h>

#include <sys/types.h>
#ifndef __MINGW32__
#include <sys/wait.h>

#if HAVE_POLL_H
#include <sys/poll.h>
#endif
#endif
#include <unistd.h>   
#include <stdio.h>    
#include <signal.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include "dialog.h"
/* TODO:
 * asynchronous lookups
 */

/* size of the text buffer used in various word-processing routines. */
#define BUFSIZE 1024
/* number of suggestions to display on each menu. */
#define MENUCOUNT 20
#define BUGEMAIL "address@hidden"

/* because we keep only one copy of the spell program running, 
 * all ispell-related variables can be static.  
 */
static pid_t spell_pid = -1;
static int fd_write[2], fd_read[2];
static int signal_set_up = 0;

/* FIXME? */
static GdkColor highlight = { 0, 255*256, 0, 0 };

static void entry_insert_cb(GtkText *gtktext, 
                gchar *newtext, guint len, guint *ppos, gpointer d);
static void set_up_signal();

int gtkspell_running() {
        return (spell_pid > 0);
}

static void error_print(const char *fmt, ...) {
        va_list ap;
        va_start(ap, fmt);
        fprintf(stderr, "gtkspell: ");
        vfprintf(stderr, fmt, ap);
        va_end(ap);
}

/* functions to interface with pipe */
static void writetext(char *text) {
        write(fd_write[1], text, strlen(text));
}
static int readpipe(char *buf, int bufsize) {
        int len;
        len = read(fd_read[0], buf, bufsize-1);
        if (len < 0) {
                error_print("read: %s\n", strerror(errno));
                return -1;
        } else if (len == 0) {
                error_print("pipe closed.\n");
                return -1;
        } else if (len == bufsize-1) {
                error_print("buffer overflowed?\n");
        }

        buf[len] = 0;
        return len;
}
static int readline(char *buf) {
        return readpipe(buf, BUFSIZE);
}

static int readresponse(char *buf) {
        int len;
        len = readpipe(buf, BUFSIZE);

        /* all ispell responses of any reasonable length should end in \n\n.
         * depending on the speed of the spell checker, this may require more
         * reading. */
        if (len >= 2 && (buf[len-1] != '\n' || buf[len-2] != '\n')) {
                len += readpipe(buf+len, BUFSIZE-len);
        }

        /* now we can remove all of the the trailing newlines. */
        while (len > 0 && buf[len-1] == '\n')
                buf[--len] = 0;

        return len;
}


void gtkspell_stop() {
#ifndef __MINGW32__
        if (gtkspell_running()) {
                kill(spell_pid, SIGQUIT); /* FIXME: is this the correct signal? 
*/
                spell_pid = -1;
        }
#endif
}

int gtkspell_start(char *path, char * args[]) {
#ifndef __MINGW32__
        int fd_error[2];
        char buf[BUFSIZE];

        if (gtkspell_running()) {
                error_print("gtkspell_start called while already running.\n");
                gtkspell_stop();
        }

        if (!signal_set_up) {
                set_up_signal();
                signal_set_up = 1;
        }

        pipe(fd_write);
        pipe(fd_read);
        pipe(fd_error);

        spell_pid = fork();
        if (spell_pid < 0) {
                error_print("fork: %s\n", strerror(errno));
                return -1;
        } else if (spell_pid == 0) {
                dup2(fd_write[0], 0);
                dup2(fd_read[1], 1);
                dup2(fd_error[1], 2);
                close(fd_read[0]);
                close(fd_error[0]);
                close(fd_write[1]);

                if (path == NULL) {
                        if (execvp(args[0], args) < 0) 
                                error_print("execvp('%s'): %s\n", args[0], 
strerror(errno));
                } else {
                        if (execv(path, args) < 0) 
                                error_print("execv('%s'): %s\n", path, 
strerror(errno));
                }
                /* if we get here, we failed.
                 * send some text on the pipe to indicate status.
                 */
                write(fd_read[1], "!", 1);

                _exit(0);
        } else {
                /* there are at least two ways to fail:
                 * - the exec() can fail
                 * - the exec() can succeed, but the program can dump the help 
screen
                 * we must check for both.
                 */

                #if HAVE_POLL_H
                struct pollfd fds[2];

                fds[0].fd = fd_error[0];
                fds[0].events = POLLIN | POLLERR;
                fds[1].fd = fd_read[0];
                fds[1].events = POLLIN | POLLERR;
                if (poll(fds, 2, 2000) <= 0) {
                        /* FIXME: is this needed? */
                        error_print("Timed out waiting for spell command.\n");
                        gtkspell_stop();
                        return -1;
                }
                

                if (fds[0].revents) { /* stderr readable? */
                        error_print("Spell command printed on stderr -- 
probably failed.\n");
                        gtkspell_stop();
                        return -1;
                }
                
                #endif
                
                readline(buf);
                /* ispell should print something like this:
                 * @(#) International Ispell Version 3.1.20 10/10/95
                 * if it doesn't, it's an error. */
                if (buf[0] != '@') {
                        gtkspell_stop();
                        do_error_dialog(_("Ispell exited abnormally.\n You 
probably specified a invalid dictionary."),
                                        _("Ispell error"));

                        return -1;
                }
        }

        /* put ispell into terse mode.  
         * this makes it not respond on correctly spelled words. */
        sprintf(buf, "!\n");
        writetext(buf);
#endif
        return 0;
}

static GList* misspelled_suggest(char *word) {
        char buf[BUFSIZE];
        char *newword;
        GList *l = NULL;
        int count;

        sprintf(buf, "^%s\n", word); /* guard against ispell control chars */
        writetext(buf);
        readresponse(buf);

        switch (buf[0]) { /* first char is ispell command. */
                case 0: /* no response: word is ok. */
                        return NULL;
                case '&': /* misspelled, with suggestions */
                        /* & <orig> <count> <ofs>: <miss>, <miss>, <guess>, ... 
*/
                        strtok(buf, " "); /* & */
                        newword = strtok(NULL, " "); /* orig */
                        l = g_list_append(l, g_strdup(newword));
                        newword = strtok(NULL, " "); /* count */
                        count = atoi(newword);
                        strtok(NULL, " "); /* ofs: */

                        while ((newword = strtok(NULL, ",")) != NULL) {
                                int len = strlen(newword);
                                if (newword[len-1] == ' ' || newword[len-1] == 
'\n') 
                                        newword[len-1] = 0;
                                if (count == 0) {
                                        g_list_append(l, NULL); /* signal the 
"suggestions" */
                                }
                                /* add it to the list, skipping the initial 
space. */
                                l = g_list_append(l, 
                                                g_strdup(newword[0] == ' ' ? 
newword+1 : newword));

                                count--;
                        }
                        return l;

                case '#': /* misspelled, no suggestions */
                        /* # <orig> <ofs> */
                        strtok(buf, " "); /* & */
                        newword = strtok(NULL, " "); /* orig */
                        l = g_list_append(l, g_strdup(newword));
                        return l;
                default:
                        error_print("Unsupported spell command '%c'.\n"
                                        "This is a bug; mail " BUGEMAIL " about 
it.\n", buf[0]);
        }
        return NULL;
}

static int misspelled_test(char *word) {
        char buf[BUFSIZE];
        sprintf(buf, "^%s\n", word); /* guard against ispell control chars */
        writetext(buf);
        readresponse(buf);

        if (buf[0] == 0) {
                return 0;
        } else if (buf[0] == '&' || buf[0] == '#') {
                return 1;
        }
        
        error_print("Unsupported spell command '%c'.\n"
                        "This is a bug; mail " BUGEMAIL " about it.\n", buf[0]);
        return -1;
}

static gboolean iswordsep(char c) {
        return !isalpha(c) && c != '\'';
}

static gboolean get_word_from_pos(GtkText* gtktext, int pos, char* buf, 
                int *pstart, int *pend) {
        gint start, end;

        if (iswordsep(GTK_TEXT_INDEX(gtktext, pos))) return FALSE;

        for (start = pos; start >= 0; --start) {
                if (iswordsep(GTK_TEXT_INDEX(gtktext, start))) break;
        }
        start++;

        for (end = pos; end <= gtk_text_get_length(gtktext); end++) {
                if (iswordsep(GTK_TEXT_INDEX(gtktext, end))) break;
        }

        if (buf) {
                for (pos = start; pos < end; pos++) 
                        buf[pos-start] = GTK_TEXT_INDEX(gtktext, pos);
                buf[pos-start] = 0;
        }

        if (pstart) *pstart = start;
        if (pend) *pend = end;

        return TRUE;
}

static gboolean get_curword(GtkText* gtktext, char* buf, 
                int *pstart, int *pend) {
        int pos = gtk_editable_get_position(GTK_EDITABLE(gtktext));
        return get_word_from_pos(gtktext, pos, buf, pstart, pend);
}

static void change_color(GtkText *gtktext, 
                int start, int end, GdkColor *color) {
        char *newtext = gtk_editable_get_chars(GTK_EDITABLE(gtktext), start, 
end);
        gtk_text_freeze(gtktext);
        gtk_signal_handler_block_by_func(GTK_OBJECT(gtktext), 
                        GTK_SIGNAL_FUNC(entry_insert_cb), NULL);
        
        gtk_text_set_point(gtktext, start);

        if(newtext && end-start > 0)
        {
                gtk_text_forward_delete(gtktext, end-start);
                gtk_text_insert(gtktext, NULL, color, NULL, newtext, end-start);
        }

        gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtktext), 
                        GTK_SIGNAL_FUNC(entry_insert_cb), NULL);
        gtk_text_thaw(gtktext);
        g_free(newtext);
}

static gboolean check_at(GtkText *gtktext, int from_pos) {
        int start, end;
        char buf[BUFSIZE];

        if (!get_word_from_pos(gtktext, from_pos, buf, &start, &end)) {
                return FALSE;
        }

        if (misspelled_test(buf)) {
                if (highlight.pixel == 0) {
                        /* add an entry for the highlight in the color map. */
                        GdkColormap *gc = 
gtk_widget_get_colormap(GTK_WIDGET(gtktext));
                        gdk_colormap_alloc_color(gc, &highlight, FALSE, TRUE);;
                }
                change_color(gtktext, start, end, &highlight);
                return TRUE;
        } else { 
                change_color(gtktext, start, end, 
                                &(GTK_WIDGET(gtktext)->style->fg[0]));
                return FALSE;
        }
}

void gtkspell_check_all(GtkText *gtktext) {
        guint origpos;
        guint pos = 0;
        guint len;
        float adj_value;
        
        if (!gtkspell_running()) return;
        
        len = gtk_text_get_length(gtktext);

        adj_value = gtktext->vadj->value;
        gtk_text_freeze(gtktext);
        origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));
        while (pos < len) {
                while (pos < len && iswordsep(GTK_TEXT_INDEX(gtktext, pos)))
                        pos++;
                while (pos < len && !iswordsep(GTK_TEXT_INDEX(gtktext, pos)))
                        pos++;
                if (pos > 0)
                        check_at(gtktext, pos-1);
        }
        gtk_text_thaw(gtktext);
        gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
}

static void entry_insert_cb(GtkText *gtktext, 
                gchar *newtext, guint len, guint *ppos, gpointer d) {
        int origpos;

        if (!gtkspell_running()) return;

        gtk_signal_handler_block_by_func(GTK_OBJECT(gtktext),
                                         GTK_SIGNAL_FUNC(entry_insert_cb),
                                         NULL);
        gtk_text_insert(GTK_TEXT(gtktext), NULL,
                        &(GTK_WIDGET(gtktext)->style->fg[0]), NULL, newtext, 
len);
        gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtktext),
                                           GTK_SIGNAL_FUNC(entry_insert_cb),
                                           NULL);
        gtk_signal_emit_stop_by_name(GTK_OBJECT(gtktext), "insert-text");
        *ppos += len;

        origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));

        if (iswordsep(newtext[0])) {
                /* did we just end a word? */
                if (*ppos >= 2) check_at(gtktext, *ppos-2);

                /* did we just split a word? */
                if (*ppos < gtk_text_get_length(gtktext))
                        check_at(gtktext, *ppos+1);
        } else {
                /* check as they type, *except* if they're typing at the end 
(the most
                 * common case.
                 */
                if (*ppos < gtk_text_get_length(gtktext) && 
                                !iswordsep(GTK_TEXT_INDEX(gtktext, *ppos)))
                        check_at(gtktext, *ppos-1);
        }

        gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
}

static void entry_delete_cb(GtkText *gtktext,
                gint start, gint end, gpointer d) {
        int origpos;

        if (!gtkspell_running()) return;

        origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));
        check_at(gtktext, start-1);
        gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
        gtk_editable_select_region(GTK_EDITABLE(gtktext), origpos, origpos);
        /* this is to *UNDO* the selection, in case they were holding shift
         * while hitting backspace. */
}

static void replace_word(GtkWidget *w, gpointer d) {
        int start, end, newword_len;
        char *newword;
        char buf[BUFSIZE];

        /* we don't save their position, 
         * because the cursor is moved by the click. */

        gtk_text_freeze(GTK_TEXT(d));

        gtk_label_get(GTK_LABEL(GTK_BIN(w)->child), &newword);
        get_curword(GTK_TEXT(d), buf, &start, &end);

        newword_len = strlen(newword);

        gtk_text_set_point(GTK_TEXT(d), end);
        gtk_text_backward_delete(GTK_TEXT(d), end-start);
        gtk_text_insert(GTK_TEXT(d), NULL, NULL, NULL, newword, newword_len);

        gtk_text_thaw(GTK_TEXT(d));

        gtk_editable_set_position(GTK_EDITABLE(d), start+newword_len);
}

static GtkMenu *make_menu(GList *l, GtkText *gtktext) {
        GtkWidget *menu, *item;
        char *caption;
        menu = gtk_menu_new(); {
                caption = g_strdup_printf(_("Not in dictionary: %s"), 
(char*)l->data);
                item = gtk_menu_item_new_with_label(caption);
                /* I'd like to make it so this item is never selectable, like
                 * the menu titles in the GNOME panel... unfortunately, the 
GNOME
                 * panel creates their own custom widget to do this! */
                gtk_widget_show(item);
                gtk_menu_append(GTK_MENU(menu), item);

                item = gtk_menu_item_new();
                gtk_widget_show(item);
                gtk_menu_append(GTK_MENU(menu), item);

                l = l->next;
                if (l == NULL) {
                        item = gtk_menu_item_new_with_label(_("(no 
suggestions)"));
                        gtk_widget_show(item);
                        gtk_menu_append(GTK_MENU(menu), item);
                } else {
                        GtkWidget *curmenu = menu;
                        int count = 0;
                        do {
                                if (l->data == NULL && l->next != NULL) {
                                        count = 0;
                                        curmenu = gtk_menu_new();
                                        item = 
gtk_menu_item_new_with_label(_("Other Possibilities..."));
                                        gtk_widget_show(item);
                                        
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), curmenu);
                                        gtk_menu_append(GTK_MENU(curmenu), 
item);
                                        l = l->next;
                                } else if (count > MENUCOUNT) {
                                        count -= MENUCOUNT;
                                        item = 
gtk_menu_item_new_with_label("More...");
                                        gtk_widget_show(item);
                                        gtk_menu_append(GTK_MENU(curmenu), 
item);
                                        curmenu = gtk_menu_new();
                                        
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), curmenu);
                                }
                                item = 
gtk_menu_item_new_with_label((char*)l->data);
                                gtk_signal_connect(GTK_OBJECT(item), "activate",
                                                GTK_SIGNAL_FUNC(replace_word), 
gtktext);
                                gtk_widget_show(item);
                                gtk_menu_append(GTK_MENU(curmenu), item);
                                count++;
                        } while ((l = l->next) != NULL);
                }
        }
        return GTK_MENU(menu);
}

static void popup_menu(GtkText *gtktext, GdkEventButton *eb) {
        char buf[BUFSIZE];
        GList *list, *l;

        get_curword(gtktext, buf, NULL, NULL);

        list = misspelled_suggest(buf);
        if (list != NULL) {
                gtk_menu_popup(make_menu(list, gtktext), NULL, NULL, NULL, NULL,
                                eb->button, eb->time);
                for (l = list; l != NULL; l = l->next)
                        g_free(l->data);
                g_list_free(list);
        }
}

/* ok, this is pretty wacky:
 * we need to let the right-mouse-click go through, so it moves the cursor, 
 * but we *can't* let it go through, because GtkText interprets rightclicks as
 * weird selection modifiers.
 *
 * so what do we do?  forge rightclicks as leftclicks, then popup the menu. 
 * HACK HACK HACK. 
 */
static gint button_press_intercept_cb(GtkText *gtktext, GdkEvent *e, gpointer 
d) {
        GdkEventButton *eb;
        gboolean retval;

        if (!gtkspell_running()) return FALSE;

        if (e->type != GDK_BUTTON_PRESS) return FALSE;
        eb = (GdkEventButton*) e;

        if (eb->button != 3) return FALSE;

        /* forge the leftclick */
        eb->button = 1;

        gtk_signal_handler_block_by_func(GTK_OBJECT(gtktext), 
                        GTK_SIGNAL_FUNC(button_press_intercept_cb), d);
        gtk_signal_emit_by_name(GTK_OBJECT(gtktext), "button-press-event",
                        e, &retval);
        gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtktext), 
                        GTK_SIGNAL_FUNC(button_press_intercept_cb), d);
        gtk_signal_emit_stop_by_name(GTK_OBJECT(gtktext), "button-press-event");

        /* now do the menu wackiness */
        popup_menu(gtktext, eb);
        return TRUE;
}

void gtkspell_uncheck_all(GtkText *gtktext) {
        int origpos;
        char *text;
        float adj_value;

        adj_value = gtktext->vadj->value;
        gtk_text_freeze(gtktext);
        origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));
        text = gtk_editable_get_chars(GTK_EDITABLE(gtktext), 0, -1);
        gtk_text_set_point(gtktext, 0);
        gtk_text_forward_delete(gtktext, gtk_text_get_length(gtktext));
        gtk_text_insert(gtktext, NULL, NULL, NULL, text, strlen(text));
        gtk_text_thaw(gtktext);

        gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
        gtk_adjustment_set_value(gtktext->vadj, adj_value);
}

void gtkspell_attach(GtkText *gtktext) {
        gtk_signal_connect(GTK_OBJECT(gtktext), "insert-text",
                GTK_SIGNAL_FUNC(entry_insert_cb), NULL);
        gtk_signal_connect_after(GTK_OBJECT(gtktext), "delete-text",
                GTK_SIGNAL_FUNC(entry_delete_cb), NULL);
        gtk_signal_connect(GTK_OBJECT(gtktext), "button-press-event",
                        GTK_SIGNAL_FUNC(button_press_intercept_cb), NULL);
}

void gtkspell_detach(GtkText *gtktext) {
        gtk_signal_disconnect_by_func(GTK_OBJECT(gtktext),
                GTK_SIGNAL_FUNC(entry_insert_cb), NULL);
        gtk_signal_disconnect_by_func(GTK_OBJECT(gtktext),
                GTK_SIGNAL_FUNC(entry_delete_cb), NULL);
        gtk_signal_disconnect_by_func(GTK_OBJECT(gtktext), 
                        GTK_SIGNAL_FUNC(button_press_intercept_cb), NULL);

        gtkspell_uncheck_all(gtktext);
}

static void sigchld(int param) {
#ifndef __MINGW32__
        if (gtkspell_running() &&
                (waitpid(spell_pid, NULL, WNOHANG) == spell_pid)) {
                spell_pid = 0;
        } else {
                /* a default SIGCHLD handler.
                 * what else to do here? */
                waitpid(-1, NULL, WNOHANG);
        }
#endif
}

static void set_up_signal() {
#ifndef __MINGW32__
        struct sigaction sigact;
        memset(&sigact, 0, sizeof(struct sigaction));

        sigact.sa_handler = sigchld;
        sigaction(SIGCHLD, &sigact, NULL);
#endif
}

--- NEW FILE: gtkspell.h ---
/* gtkspell - a spell-checking addon for GtkText
 * Copyright (c) 2000 Evan Martin.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 */

#ifndef __gtkspell_h__
#define __gtkspell_h__

/* PLEASE NOTE that this API is unstable and subject to change. */
#define GTKSPELL_VERSION "0.3.1"

extern int gtkspell_start(char *path, char *args[]);
/* Spawns the spell checking program.
 *
 * Arguments:
 *  - "path" should be the full path to the spell checking program, or NULL
 *    if you want to search the PATH for args[0].
 *  - "args" should be a array of arguments to the spell checking program.
 *    The first element should be the name of the program.
 *    You should give the argument to run the spell checking program in the
 *    "embedded" mode.  for ispell, this is "-a".
 *    The last element should be NULL.
 * Return:
 *  0 on success, and -1 on error.
 *
 * Example:
 *  char *args[] = { "ispell", "-a", NULL };
 *  if (gtkspell_start(NULL, args) < 0) {
 *      fprintf(stderr, "Unable to start GtkSpell.\n");
 *      return -1;
 *  }
 *
 */


extern void gtkspell_stop();
/* Stop the spellchecking program.
 * This kills the spell checker's process and frees memory.
 */

extern int gtkspell_running();
/* Is gtkspell running?
 *
 * Returns:
 *      nonzero if it running
 *      zero if is not running
 *
 * Example:
 *  if (gtkspell_running())
 *      printf("gtkspell is running.\n");
 */

extern void gtkspell_attach(GtkText *text);
/* Attach GtkSpell to a GtkText Widget.
 * This enables checking as you type and the popup menu.
 *
 * Arguments:
 *  - "text" is the widget to which GtkSpell should attach.
 *
 * Example:
 *  GtkWidget *text;
 *  text = gtk_text_new(NULL, NULL); 
 *  gtk_text_set_editable(GTK_TEXT(text), TRUE);
 *  gtkspell_attach(GTK_TEXT(text));
 */  

void gtkspell_detach(GtkText *gtktext);
/* Detach GtkSpell from a GtkText widget.
 * 
 * Arguments:
 *  - "text" is the widget from which GtkSpell should detach.
 * 
 */ 

void gtkspell_check_all(GtkText *gtktext);
/* Check and highlight the misspelled words.
 * Note that the popup menu will not work unless you gtkspell_attach().
 *
 * Arguments:
 *  - "text" is the widget to check.
 */

void gtkspell_uncheck_all(GtkText *gtktext);
/* Remove all of the highlighting from the widget.
 *
 * Arguments:
 *  - "text" is the widget to check.
 */

#endif /* __gtkspell_h__ */

--- NEW FILE: gtkutils.c ---
/*
 * Ayttm 
 *
 * Copyright (C) 1999, Torrey Searle <address@hidden>
 *
 * 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 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 "gtkutils.h"
#include "gtk_globals.h"

void gtkut_set_pixmap_from_xpm(char **xpm, GtkPixmap *pixmap)
{
        if (xpm && pixmap) {
                GdkPixmap *tpx= NULL;
                GdkBitmap *tbx= NULL;
                tpx = gdk_pixmap_create_from_xpm_d(statuswindow->window, &tbx, 
                                                NULL, xpm);
                gtk_pixmap_set(pixmap, tpx, tbx);
        }
}

--- NEW FILE: gtkutils.h ---
/*
 * Ayttm 
 *
 * Copyright (C) 1999, Torrey Searle <address@hidden>
 *
 * 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 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
 *
 */
#ifndef __GTKUTILS_H__
#define __GTKUTILS_H__

#include <gtk/gtk.h>
#include <gdk/gdk.h>

void gtkut_set_pixmap_from_xpm(char **xpm, GtkPixmap *pixmap);

#endif

Index: Makefile.am
===================================================================
RCS file: /cvsroot/ayttm/ayttm/src/gtk/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.am 28 Jan 2003 00:35:05 -0000      1.1
+++ Makefile.am 28 Jan 2003 08:08:55 -0000      1.2
@@ -1,8 +1,11 @@
 noinst_LTLIBRARIES = libayttmgtk.la
 
 libayttmgtk_la_SOURCES = \
+       about.c about.h \
        extgtktext.c extgtktext.h \
-       gtk_eb_html.c gtk_eb_html.h
+       gtk_eb_html.c gtk_eb_html.h \
+       gtkspell.c gtkspell.h \
+       gtkutils.c gtkutils.h
 
 INCLUDES = \
        -I.. \





reply via email to

[Prev in Thread] Current Thread [Next in Thread]