예제 #1
0
파일: main.c 프로젝트: wavs/ocre
/* fct qui balance du texte dans l'editeur */
void on_text_show (GtkImageMenuItem* test, gpointer user_data)
{
  GUI_* guisex;
  GtkTextBuffer *txtbuffer;
  (void)test;
  guisex = (GUI_ *)user_data;
  gtkspell_new_attach(GTK_TEXT_VIEW(guisex->textview), "fr", NULL);
  txtbuffer = gtk_text_view_get_buffer
    (GTK_TEXT_VIEW(guisex->textview));
  gtk_text_buffer_set_text
    (txtbuffer,"Hello\n",-1);
}
예제 #2
0
파일: spell.c 프로젝트: Debian/gpdftext
void
spell_language_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer user_data)
{
#ifdef HAVE_GTKSPELL
	Ebook *ebook;
	GConfValue *value;
	GtkSpell *spell;
	const gchar *gconf_lang;
	gchar *lang;
	GtkWidget * window, * G_GNUC_UNUSED spell_check;
	GtkTextView * text_view;
	gboolean spellcheck_wanted;

	g_return_if_fail (user_data);

	ebook = (Ebook *) user_data;
	value = gconf_entry_get_value (entry);
	gconf_lang = gconf_value_get_string (value);
	window = GTK_WIDGET(gtk_builder_get_object (ebook->builder, "gpdfwindow"));
	spell_check = GTK_WIDGET(gtk_builder_get_object (ebook->builder, "spellcheckmenuitem"));
	text_view = GTK_TEXT_VIEW(gtk_builder_get_object (ebook->builder, "textview"));

	if (*gconf_lang == '\0' || gconf_lang == NULL)
		lang = NULL;
	else
		lang = g_strdup (gconf_lang);

	if (window)
	{
		spellcheck_wanted = gconf_client_get_bool (ebook->client, ebook->spell_check.key, NULL);
		spell = gtkspell_get_from_text_view (text_view);
		if (spellcheck_wanted)
		{
			if (spell && lang)
				/* Only if we have both spell and lang non-null we can use _set_language() */
				gtkspell_set_language (spell, lang, NULL);
			else
			{
				/* We need to create a new spell widget if we want to use lang == NULL (use default lang)
				 * or if the spell isn't initialized */
				if (spell)
					gtkspell_detach (spell);
				spell = gtkspell_new_attach (text_view, lang, NULL);
			}
			gtkspell_recheck_all (spell);
		}
	}
	spell_language_select_menuitem (ebook, lang);
	g_free (lang);
#endif /* HAVE_GTKSPELL */
}
예제 #3
0
파일: jamview.c 프로젝트: nightmorph/LogJam
void
jam_view_set_doc(JamView *view, JamDoc *doc) {
	view->doc = doc;

	undomgr_detach(view->undomgr, view->entry);

	if (view->account != jam_doc_get_account(doc))
		jam_view_account_changed(view);
	g_signal_connect_swapped(G_OBJECT(doc), "notify::account",
			G_CALLBACK(jam_view_account_changed), view);
	g_signal_connect_swapped(G_OBJECT(doc), "update_doc",
			G_CALLBACK(jam_view_store_doc), view);
	g_signal_connect_swapped(G_OBJECT(doc), "entry_changed",
			G_CALLBACK(jam_view_load_doc), view);

	jam_view_load_conf(view);
	jam_view_load_doc(view);

	/* XXX: gtkspell gets confused if you detach its document,
	 * so we detach the spell checker completely, then reattach
	 * it at the end. */
#ifdef HAVE_GTKSPELL
	if (conf.options.usespellcheck && view->entry) {
		GtkSpell *spell;
		spell = gtkspell_get_from_text_view(GTK_TEXT_VIEW(view->entry));
		if (spell)
			gtkspell_detach(spell);
	}
#endif /* HAVE_GTKSPELL */

	gtk_text_view_set_buffer(GTK_TEXT_VIEW(view->entry),
			jam_doc_get_text_buffer(doc));

#ifdef HAVE_GTKSPELL
	if (conf.options.usespellcheck) {
		GError *err = NULL;
		if (gtkspell_new_attach(GTK_TEXT_VIEW(view->entry),
					conf.spell_language, &err) == NULL) {
			GtkWindow *toplevel;
			toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
			jam_warning(toplevel,
					_("GtkSpell error: %s"), err->message);
			g_error_free(err);
		}
	}
#endif /* HAVE_GTKSPELL */

	undomgr_attach(view->undomgr, view->entry);
}
예제 #4
0
파일: spell.c 프로젝트: Debian/gpdftext
void
spellcheck_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer user_data)
{
#ifdef HAVE_GTKSPELL
	GConfValue *value;
	GtkSpell *spell;
	GtkWidget * dict, * spell_check, * spell_button;
	GtkTextView * text_view;
	gboolean state;
	gchar *lang;
	Ebook *ebook;

	ebook = (Ebook *) user_data;
	value = gconf_entry_get_value (entry);
	state = gconf_value_get_bool (value);
	dict = GTK_WIDGET(gtk_builder_get_object (ebook->builder, "langboxentry"));

	gtk_widget_set_sensitive (dict, state);

	text_view = GTK_TEXT_VIEW(gtk_builder_get_object (ebook->builder, "textview"));
	spell_check = GTK_WIDGET(gtk_builder_get_object (ebook->builder, "spellcheckmenuitem"));
	spell_button = GTK_WIDGET(gtk_builder_get_object (ebook->builder, "spellcheckbutton"));
	spell = gtkspell_get_from_text_view (text_view);
	lang = gconf_client_get_string (ebook->client, ebook->language.key, NULL);

	if (state)
	{
		if (!spell)
			gtkspell_new_attach (text_view,
						(lang == NULL || *lang == '\0') ? NULL : lang, NULL);
	}
	else {
		if (spell) {
			gtkspell_detach (spell);
		}
	}
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (spell_check), state);
	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (spell_button), state);

#endif /* HAVE_GTKSPELL */
}
예제 #5
0
파일: jamview.c 프로젝트: nightmorph/LogJam
void
jam_view_settings_changed(JamView *view) {
#ifdef HAVE_GTKSPELL
	GtkSpell *spell;
	GError *err = NULL;
	spell = gtkspell_get_from_text_view(GTK_TEXT_VIEW(view->entry));
	if (conf.options.usespellcheck) {
		GtkWindow *toplevel;
		toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
		if (spell) {
			if (!gtkspell_set_language(spell, conf.spell_language, &err)) {
				jam_warning(toplevel,
						_("GtkSpell error: %s"), err->message);
				g_error_free(err);
			}
		} else {
			GError *err = NULL;
			if (gtkspell_new_attach(GTK_TEXT_VIEW(view->entry), conf.spell_language , &err) == NULL) {
				jam_warning(toplevel,
						_("GtkSpell error: %s"), err->message);
				conf.options.usespellcheck = FALSE;
				g_error_free(err);
			}
		}
	} else {
		if (spell)
			gtkspell_detach(spell);
	}
#endif
	if (conf.uifont)
		jam_widget_set_font(view->entry, conf.uifont);

	if (view->musicbar) {
	    /* There are many cleaner ways to add/remove the Refresh button when
	     * the music preference has changed, but this works fine. */
		music_remove(view);
		music_add(view);
	}
}
예제 #6
0
파일: pomieszczenie.c 프로젝트: Lamieur/Lac
void zrob_okno_Pomieszczenia( void )
{
    int i, j;
    GtkWidget *tree, *text;
    GtkTable *table;
    char nazwa[ MIL ];

    ZNAJDZ_KONTROLKE( dpom.Pomieszczenie, "oknopomieszczenie" );
    ZNAJDZ_KONTROLKE( dpom.entry_nazwa, "pom_entry_nazwa" );
    ZNAJDZ_KONTROLKE( dpom.entry_miejscownik, "pom_entry_miejscownik" );
    ZNAJDZ_KONTROLKE( text, "pom_text_opis" );

    /* tego nie potrafi GLADE, kaka */
    gtk_widget_modify_font( text, font_desc );

#if !defined( BEZ_GTKSPELL )
    gtkspell_new_attach( GTK_TEXT_VIEW( text ), NULL, NULL );
#endif

    ZNAJDZ_KONTROLKE2( dpom.buffer, "pom_buffer_opis", GTK_TEXT_BUFFER );

    ZNAJDZ_KONTROLKE( dpom.combobox_podloze, "pom_combo_podloze" );
    ZNAJDZ_KONTROLKE( dpom.spin_pojemnosc, "pom_spin_pojemnosc" );
    ZNAJDZ_KONTROLKE( dpom.spin_ruch, "pom_spin_ruch" );
    ZNAJDZ_KONTROLKE( dpom.entry_antirace, "pom_entry_antirace" );
    ZNAJDZ_KONTROLKE( dpom.entry_anticlass, "pom_entry_anticlass" );

    for ( i = 0; i < 10; i++ )
    {
	sprintf( nazwa, "pom_label_%d", i );
	ZNAJDZ_KONTROLKE( dpom.label[ i ], nazwa );

	sprintf( nazwa, "pom_button_%d", i );
	ZNAJDZ_KONTROLKE( dpom.button[ i ], nazwa );
	gtk_signal_connect( GTK_OBJECT( dpom.button[ i ] ), "enter-notify-event",
			    GTK_SIGNAL_FUNC( zmien_wyjscie ), GINT_TO_POINTER( i ) );
	gtk_signal_connect( GTK_OBJECT( dpom.button[ i ] ), "clicked",
			    GTK_SIGNAL_FUNC( edytuj_wyjscie ), GINT_TO_POINTER( i ) );
    }

    ZNAJDZ_KONTROLKE2( dpom.store_resety, "pom_store_resety", GTK_LIST_STORE );
    ZNAJDZ_KONTROLKE( tree, "pom_treeview_resety" );
    dpom.select_reset = gtk_tree_view_get_selection( GTK_TREE_VIEW( tree ) );

    ZNAJDZ_KONTROLKE( dpom.button_opisy, "pom_button_opisy" );
    ZNAJDZ_KONTROLKE( dpom.label_opisy, "pom_label_opisy" );
    ZNAJDZ_KONTROLKE( dpom.label_wyjscie, "pom_label_wyjscie" );
    ZNAJDZ_KONTROLKE( dpom.button_progi, "pom_button_progi" );
    ZNAJDZ_KONTROLKE( dpom.button_poprz, "pom_button_poprz" );
    ZNAJDZ_KONTROLKE( dpom.button_nast, "pom_button_nast" );
    ZNAJDZ_KONTROLKE( dpom.label_flagi, "pom_label_flagi" );
    ZNAJDZ_KONTROLKE( dpom.vbox_pulapka, "pom_vbox_pulapka" );
    ZNAJDZ_KONTROLKE2( dpom.radio_pulapka1, "pom_radio_pulapka1", GTK_RADIO_BUTTON );
    ZNAJDZ_KONTROLKE2( dpom.radio_pulapka2, "pom_radio_pulapka2", GTK_RADIO_BUTTON );
    ZNAJDZ_KONTROLKE2( dpom.buffer_pulapka, "pom_buffer_pulapka", GTK_TEXT_BUFFER );
    ZNAJDZ_KONTROLKE2( dpom.check_pulapka, "pom_check_pulapka", GTK_CHECK_BUTTON );

    ZNAJDZ_KONTROLKE2( table, "pom_table_zachowania", GTK_TABLE );
    for ( i = j = 0; room_flags_table[ i ].name; i++ )
	if ( room_flags_table[ i ].available )
	{
	    dpom.check[ j ] = gtk_check_button_new_with_label( _( room_flags_table[ i ].name ) );
	    gtk_widget_set_tooltip_text( dpom.check[ j ], _( room_flags_table[ i ].tooltip ) );
	    gtk_table_attach( table, dpom.check[ j ],
		j % 2, j % 2 + 1, j / 2, j / 2 + 1,
		GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0 );
	    g_signal_connect( G_OBJECT( dpom.check[ j ] ), "toggled",
		G_CALLBACK( zmiana_flagi_pomieszczenia ), NULL );
	    dpom.check_na_flage[ j ] = room_flags_table[ i ].bitv;
	    j++;
	}
    gtk_widget_show_all( GTK_WIDGET( table ) );

    return;
}
예제 #7
0
파일: pdf.c 프로젝트: Debian/gpdftext
/**
 called repeatedly to add more text to the editor as each
 page is read from the PDF file, via g_timeout_add.

 Spelling needs to be turned off during loading, re-attached it at the end
 if GConf says spelling should be enabled.

 This function is asynchronous - a background task.
 Don't do things with the progress bar or status bar whilst a load
 task could be running.
 */
static gboolean
load_pdf (gpointer data)
{
	GtkProgressBar * progressbar;
	GtkStatusbar * statusbar;
	GtkTextView * text_view;
	GtkTextBuffer * buffer;
	gchar *page, * msg, * G_GNUC_UNUSED lang;
	gdouble fraction, step, width, height;
	PopplerPage * PDFPage;
	const gchar * str;
	gint pages;
	guint id;
	Equeue * queue;

	queue= (Equeue *)data;
	text_view = GTK_TEXT_VIEW(gtk_builder_get_object (queue->ebook->builder, "textview"));
	buffer = gtk_text_view_get_buffer (text_view);
	if (!queue)
	{
		gtk_text_buffer_end_user_action (buffer);
		return FALSE;
	}
	if (!queue->ebook)
	{
		gtk_text_buffer_end_user_action (buffer);
		return FALSE;
	}
	progressbar = GTK_PROGRESS_BAR(gtk_builder_get_object (queue->ebook->builder, "progressbar"));
	statusbar = GTK_STATUSBAR(gtk_builder_get_object (queue->ebook->builder, "statusbar"));
	id = gtk_statusbar_get_context_id (statusbar, PACKAGE);
	pages = poppler_document_get_n_pages (queue->ebook->PDFDoc);
	if (queue->c >= pages)
	{
		lang = gconf_client_get_string (queue->ebook->client,
			queue->ebook->language.key, NULL);
#ifdef HAVE_GTKSPELL
		/* spell_attach is already a background task. */
		if (queue->spell_state)
			gtkspell_new_attach (text_view,
				(lang == NULL || *lang == '\0') ? NULL : lang, NULL);
#endif
		gtk_progress_bar_set_text (progressbar, "");
		gtk_progress_bar_set_fraction (progressbar, 0.0);
		if (queue->ebook->utf8_count > 0)
		{
			/* Translators: Please try to keep this string brief,
			 there often isn't a lot of room in the statusbar. */
			str = ngettext ("%ld non-UTF8 character was removed",
				"%ld non-UTF-8 characters were removed", queue->ebook->utf8_count);
			msg = g_strdup_printf (str, queue->ebook->utf8_count);
			id = gtk_statusbar_get_context_id (statusbar, PACKAGE);
			gtk_statusbar_push (statusbar, id, msg);
			g_free (msg);
		}
		else
		{
			gtk_statusbar_push (statusbar, id, _("Done"));
		}
		return FALSE;
	}
	PDFPage = poppler_document_get_page (queue->ebook->PDFDoc, queue->c);
	fraction = 0.0;
	/* fraction never reaches 1.0 - allow room for spelling attachment. */
	if (queue->spell_state)
		step = 0.90/(gdouble)pages;
	else
		step = 0.99/(gdouble)pages;
	fraction += step * queue->c;
	/* update progress bar as we go */
	gtk_progress_bar_set_fraction (progressbar, fraction);
	poppler_page_get_size (PDFPage, &width, &height);
	queue->rect->x2 = width;
	queue->rect->y2 = height;
#if POPPLER_CHECK_VERSION(0, 14, 1)
	page = poppler_page_get_selected_text (PDFPage, POPPLER_SELECTION_LINE, queue->rect);
#else
    page = poppler_page_get_text (PDFPage, POPPLER_SELECTION_LINE, queue->rect);
#endif
	set_text (queue->ebook, page, queue->lines, queue->pagenums, queue->hyphens);
	g_free (page);
	queue->c++;
	/* add the page to the progressbar count. */
	msg = g_strdup_printf ("%d/%d", queue->c, pages);
	gtk_progress_bar_set_text (progressbar, msg);
	g_free (msg);
	/* more to do yet, so return TRUE to call me again. */
	return TRUE;
}
void
sp_text_edit_dialog (void)
{
    if (!dlg) {

        gchar title[500];
        sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_TEXT), title);
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();

        dlg = sp_window_new (title, TRUE);
        if (x == -1000 || y == -1000) {
            x = prefs->getInt(prefs_path + "x", -1000);
            y = prefs->getInt(prefs_path + "y", -1000);
        }
        if (w ==0 || h == 0) {
            w = prefs->getInt(prefs_path + "w", 0);
            h = prefs->getInt(prefs_path + "h", 0);
        }

//        if (x<0) x=0;
//        if (y<0) y=0;

        if (w && h)
            gtk_window_resize ((GtkWindow *) dlg, w, h);
        if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE))) {
            gtk_window_move ((GtkWindow *) dlg, x, y);
        } else {
            gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
        }


        sp_transientize (dlg);
        wd.win = dlg;
        wd.stop = 0;
        g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd );

        gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg );

        gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_text_edit_dialog_destroy), dlg );
        gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_text_edit_dialog_delete), dlg );
        g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_text_edit_dialog_delete), dlg );

        g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg );
        g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg );

        gtk_window_set_policy (GTK_WINDOW (dlg), TRUE, TRUE, FALSE);

        GtkTooltips *tt = gtk_tooltips_new();

        // box containing the notebook and the bottom buttons
        GtkWidget *mainvb = gtk_vbox_new (FALSE, 0);
        gtk_container_add (GTK_CONTAINER (dlg), mainvb);

        // notebook
        GtkWidget *nb = gtk_notebook_new ();
        gtk_box_pack_start (GTK_BOX (mainvb), nb, TRUE, TRUE, 0);
        g_object_set_data (G_OBJECT (dlg), "notebook", nb);



        // Font tab
        {
            GtkWidget *l = gtk_label_new (_("Font"));
            GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN);
            gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN);
            gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l);

            /* HBox containing font selection and layout */
            GtkWidget *hb = gtk_hbox_new (FALSE, 0);
            gtk_box_pack_start (GTK_BOX (vb), hb, TRUE, TRUE, 0);

            // font and style selector
            GtkWidget *fontsel = sp_font_selector_new ();
            g_signal_connect ( G_OBJECT (fontsel), "font_set", G_CALLBACK (sp_text_edit_dialog_font_changed), dlg );

            g_signal_connect_swapped ( G_OBJECT (g_object_get_data (G_OBJECT(fontsel), "family-treeview")),
                                      "row-activated",
                                      G_CALLBACK (gtk_window_activate_default),
                                      dlg);

            gtk_box_pack_start (GTK_BOX (hb), fontsel, TRUE, TRUE, 0);
            g_object_set_data (G_OBJECT (dlg), "fontsel", fontsel);

            // Layout
            {
                GtkWidget *f = gtk_frame_new (_("Layout"));
                gtk_box_pack_start (GTK_BOX (hb), f, FALSE, FALSE, 4);
                GtkWidget *l_vb = gtk_vbox_new (FALSE, VB_MARGIN);
                gtk_container_add (GTK_CONTAINER (f), l_vb);

                {
                    GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN);
                    GtkWidget *group;

                    // align left
                    {
                        // TODO - replace with Inkscape-specific call
                        GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_LEFT, GTK_ICON_SIZE_LARGE_TOOLBAR );
                        GtkWidget *b = group = gtk_radio_button_new (NULL);
                        gtk_tooltips_set_tip (tt, b, _("Align lines left"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg);
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE );
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), "text_anchor_start", b);
                    }

                    // align center
                    {
                        // TODO - replace with Inkscape-specific call
                        GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_CENTER, GTK_ICON_SIZE_LARGE_TOOLBAR );
                        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
                        /* TRANSLATORS: `Center' here is a verb. */
                        gtk_tooltips_set_tip (tt, b, _("Center lines"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg );
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE);
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), "text_anchor_middle", b);
                    }

                    // align right
                    {
                        // TODO - replace with Inkscape-specific call
                        GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_RIGHT, GTK_ICON_SIZE_LARGE_TOOLBAR );
                        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
                        gtk_tooltips_set_tip (tt, b, _("Align lines right"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg );
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE);
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), "text_anchor_end", b);
                    }

                    // align justify
                    {
                        // TODO - replace with Inkscape-specific call
                        GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_FILL, GTK_ICON_SIZE_LARGE_TOOLBAR );
                        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
                        gtk_tooltips_set_tip (tt, b, _("Justify lines"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg );
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE);
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), "text_anchor_justify", b);
                    }

                    gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0);
                }


                {
                    GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN);
                    GtkWidget *group;

                    // horizontal
                    {
                        GtkWidget *px = sp_icon_new( Inkscape::ICON_SIZE_LARGE_TOOLBAR,
                                                      INKSCAPE_STOCK_WRITING_MODE_LR );
                        GtkWidget *b = group = gtk_radio_button_new (NULL);
                        gtk_tooltips_set_tip (tt, b, _("Horizontal text"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg );
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE);
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_LR, b);
                    }

                    // vertical
                    {
                        GtkWidget *px = sp_icon_new( Inkscape::ICON_SIZE_LARGE_TOOLBAR,
                                                      INKSCAPE_STOCK_WRITING_MODE_TB );
                        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
                        gtk_tooltips_set_tip (tt, b, _("Vertical text"), NULL);
                        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
                        g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg );
                        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE);
                        gtk_container_add (GTK_CONTAINER (b), px);
                        gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0);
                        g_object_set_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_TB, b);
                    }

                    gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0);
                }

                {
                    GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN);

                    l = gtk_label_new (_("Line spacing:"));
                    gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
                    gtk_box_pack_start (GTK_BOX (row), l, FALSE, FALSE, VB_MARGIN);

                    gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0);
                }

                {
                    GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN);

                    GtkWidget *c = gtk_combo_new ();
                    gtk_combo_set_value_in_list ((GtkCombo *) c, FALSE, FALSE);
                    gtk_combo_set_use_arrows ((GtkCombo *) c, TRUE);
                    gtk_combo_set_use_arrows_always ((GtkCombo *) c, TRUE);
                    gtk_widget_set_size_request (c, 90, -1);

                    { /* Setup strings */
                        GList *sl = NULL;
                        for (int i = 0; spacings[i]; i++) {
                            sl = g_list_prepend (sl, (void *) spacings[i]);
                        }
                        sl = g_list_reverse (sl);
                        gtk_combo_set_popdown_strings ((GtkCombo *) c, sl);
                        g_list_free (sl);
                    }

                    g_signal_connect ( (GObject *) ((GtkCombo *) c)->entry,
                                       "changed",
                                       (GCallback) sp_text_edit_dialog_line_spacing_changed,
                                       dlg );
                    gtk_box_pack_start (GTK_BOX (row), c, FALSE, FALSE, VB_MARGIN);
                    g_object_set_data (G_OBJECT (dlg), "line_spacing", c);

                    gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, VB_MARGIN);
                }
            }

            /* Font preview */
            GtkWidget *preview = sp_font_preview_new ();
            gtk_box_pack_start (GTK_BOX (vb), preview, TRUE, TRUE, 4);
            g_object_set_data (G_OBJECT (dlg), "preview", preview);
        }


        // Text tab
        {
            GtkWidget *l = gtk_label_new (_("Text"));
            GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN);
            gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN);
            gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l);

            GtkWidget *scroller = gtk_scrolled_window_new ( NULL, NULL );
            gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scroller),
                                             GTK_POLICY_AUTOMATIC,
                                             GTK_POLICY_AUTOMATIC );
            gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW(scroller), GTK_SHADOW_IN );
            gtk_widget_show (scroller);

            GtkTextBuffer *tb = gtk_text_buffer_new (NULL);
            GtkWidget *txt = gtk_text_view_new_with_buffer (tb);
            gtk_text_view_set_wrap_mode ((GtkTextView *) txt, GTK_WRAP_WORD);
#ifdef WITH_GTKSPELL
            GError *error = NULL;
            char *errortext = NULL;
            /* todo: Use computed xml:lang attribute of relevant element, if present, to specify the
               language (either as 2nd arg of gtkspell_new_attach, or with explicit
               gtkspell_set_language call in; see advanced.c example in gtkspell docs).
               sp_text_edit_dialog_read_selection looks like a suitable place. */
            if (gtkspell_new_attach(GTK_TEXT_VIEW(txt), NULL, &error) == NULL) {
                g_print("gtkspell error: %s\n", error->message);
                errortext = g_strdup_printf("GtkSpell was unable to initialize.\n"
                                            "%s", error->message);
                g_error_free(error);
            }
#endif
            gtk_widget_set_size_request (txt, -1, 64);
            gtk_text_view_set_editable (GTK_TEXT_VIEW (txt), TRUE);
            gtk_container_add (GTK_CONTAINER (scroller), txt);
            gtk_box_pack_start (GTK_BOX (vb), scroller, TRUE, TRUE, 0);
            g_signal_connect ( G_OBJECT (tb), "changed",
                               G_CALLBACK (sp_text_edit_dialog_text_changed), dlg );
            g_signal_connect (G_OBJECT (txt), "focus-in-event", G_CALLBACK (text_view_focus_in), dlg);
            g_signal_connect (G_OBJECT (txt), "focus-out-event", G_CALLBACK (text_view_focus_out), dlg);
            g_object_set_data (G_OBJECT (dlg), "text", tb);
            g_object_set_data (G_OBJECT (dlg), "textw", txt);
        }

        /* Buttons */
        GtkWidget *hb = gtk_hbox_new (FALSE, VB_MARGIN);
        gtk_container_set_border_width (GTK_CONTAINER (hb), 4);
        gtk_box_pack_start (GTK_BOX (mainvb), hb, FALSE, FALSE, 0);

        {
            GtkWidget *b = gtk_button_new_with_label (_("Set as default"));
            g_signal_connect ( G_OBJECT (b), "clicked",
                               G_CALLBACK (sp_text_edit_dialog_set_default),
                               dlg );
            gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0);
            g_object_set_data (G_OBJECT (dlg), "default", b);
        }

        {
            GtkWidget *b = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
            g_signal_connect ( G_OBJECT (b), "clicked",
                               G_CALLBACK (sp_text_edit_dialog_close), dlg );
            gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0);
        }

        {
            GtkWidget *b = gtk_button_new_from_stock (GTK_STOCK_APPLY);
            GTK_WIDGET_SET_FLAGS (b, GTK_CAN_DEFAULT | GTK_HAS_DEFAULT);
            g_signal_connect ( G_OBJECT (b), "clicked",
                               G_CALLBACK (sp_text_edit_dialog_apply), dlg );
            gtk_box_pack_end ( GTK_BOX (hb), b, FALSE, FALSE, 0 );
            g_object_set_data (G_OBJECT (dlg), "apply", b);
        }

        g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection",
                           G_CALLBACK (sp_text_edit_dialog_selection_modified), dlg);
        g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection",
                           G_CALLBACK (sp_text_edit_dialog_selection_changed), dlg);
        g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_text_edit_dialog_subselection_changed), dlg);

        gtk_widget_show_all (dlg);

        sp_text_edit_dialog_read_selection (dlg, TRUE, TRUE);
    }

    gtk_window_present ((GtkWindow *) dlg);

} // end of sp_text_edit_dialog()