static gboolean gw_spellcheck_get_line_coordinates (GwSpellcheck *spellcheck, int startindex, int endindex, int *x, int *y, int *x2, int *y2) { //Declarations GwSpellcheckPrivate *priv; int index; PangoLayout *layout; PangoRectangle rect; PangoLayoutIter *iter; int xoffset, yoffset; //Initializations priv = spellcheck->priv; layout = gtk_entry_get_layout (priv->entry); iter = pango_layout_get_iter (layout); xoffset = gw_spellcheck_get_layout_x_offset (spellcheck); yoffset = gw_spellcheck_get_layout_y_offset (spellcheck); *x = *y = *x2 = *y2 = 0; do { index = pango_layout_iter_get_index (iter); pango_layout_iter_get_char_extents (iter, &rect); if (index == startindex) { *x = PANGO_PIXELS (rect.x) + xoffset; *y = PANGO_PIXELS (rect.y + rect.height) + yoffset; } if (index == endindex - 1) { *x2 = PANGO_PIXELS (rect.width + rect.x) + xoffset + 1; *y2 = *y; } } while (pango_layout_iter_next_char (iter)); //Cleanup pango_layout_iter_free (iter); return (*x > 0 && *y > 0 && *x2 > 0 && *y2 > 0); }
void gw_spellcheck_populate_popup (GwSpellcheck *spellcheck, GtkMenu *menu) { //Sanity checks g_return_if_fail (spellcheck != NULL); g_return_if_fail (menu != NULL); //Declarations GwSpellcheckPrivate *priv = NULL; GtkWidget *menuitem = NULL, *spellmenuitem = NULL; GtkWidget *spellmenu = NULL; gint index; gint xoffset, yoffset, x, y; gint start_offset, end_offset; gint i; gchar **iter = NULL; LwMorphologyEngine *morphologyengine = NULL; //Initializations priv = spellcheck->priv; if (priv->tokens == NULL) return; morphologyengine = gw_application_get_morphologyengine (priv->application); g_return_if_fail (morphologyengine != NULL); xoffset = gw_spellcheck_get_layout_x_offset (spellcheck); yoffset = gw_spellcheck_get_layout_y_offset (spellcheck); x = priv->x - xoffset; y = priv->y - yoffset; //Since a GtkEntry is single line, we want the y to always be in the area index = _get_string_index (priv->entry, x, y); start_offset = 0; iter = priv->tokens; while (*iter != NULL && start_offset + strlen(*iter) < index) { start_offset += strlen(*iter) + 1; iter++; } if (*iter == NULL) return; end_offset = start_offset + strlen(*iter); LwMorphologyList *morphologylist = NULL; LwMorphology *morphology = NULL; gchar **suggestions = NULL; morphologylist = lw_morphologyengine_analyze (morphologyengine, *iter, TRUE); if (morphologylist == NULL) goto errored; morphology = lw_morphologylist_read (morphologylist); if (morphology == NULL) goto errored; if (morphology->spellcheck != NULL) { suggestions = g_strsplit (morphology->spellcheck, LW_MORPHOLOGY_SPELLCHECK_DELIMITOR, -1); gsize total_suggestions = g_strv_length (suggestions); if (total_suggestions > 0 && suggestions != NULL) { menuitem = gtk_separator_menu_item_new (); gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem); gtk_widget_show (menuitem); spellmenu = gtk_menu_new (); spellmenuitem = gtk_menu_item_new_with_label (gettext("_Spellcheck")); gtk_menu_item_set_submenu (GTK_MENU_ITEM (spellmenuitem), spellmenu); gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), spellmenuitem); gtk_widget_show (spellmenuitem); gchar *text = g_strdup_printf (gettext("Add \"%s\" to the dictionary"), *iter); if (text != NULL) { GtkWidget *image = gtk_image_new_from_icon_name ("gtk-add", GTK_ICON_SIZE_MENU); menuitem = gtk_menu_item_new_with_label (text); g_object_set_data_full (G_OBJECT (menuitem), "word", g_strdup (*iter), g_free); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (gw_spellcheck_add_menuitem_activated_cb), spellcheck); gtk_menu_shell_append (GTK_MENU_SHELL (spellmenu), menuitem); g_free (text); text = NULL; gtk_widget_show (menuitem); } menuitem = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (spellmenu), menuitem); gtk_widget_show (menuitem); //Menuitems for (i = 0; i < total_suggestions; i++) { menuitem = gtk_menu_item_new_with_label (suggestions[i]); g_object_set_data (G_OBJECT (menuitem), "start-offset", GINT_TO_POINTER (start_offset)); g_object_set_data (G_OBJECT (menuitem), "end-offset", GINT_TO_POINTER (end_offset)); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (gw_spellcheck_menuitem_activated_cb), spellcheck); gtk_widget_show (GTK_WIDGET (menuitem)); gtk_menu_shell_append (GTK_MENU_SHELL (spellmenu), menuitem); } } } errored: if (suggestions != NULL) g_strfreev (suggestions); suggestions = NULL; if (morphologylist != NULL) lw_morphologylist_free (morphologylist); morphologylist = NULL; }