예제 #1
0
파일: slib-editor.c 프로젝트: acli/xiphos
GtkWidget *editor_new(const gchar *title, EDITOR *e)
{
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkWidget *editor;
	GError *error = NULL;

	editor = gtkhtml_editor_new();
	e->window = editor;
	e->html_widget =
	    GTK_WIDGET(gtkhtml_editor_get_html(GTKHTML_EDITOR(editor)));
	gtk_window_set_title(GTK_WINDOW(editor), title);

	set_window_icon(GTK_WINDOW(editor));

	manager = gtkhtml_editor_get_ui_manager(GTKHTML_EDITOR(editor));
	if (e->type == STUDYPAD_EDITOR)
		gtk_ui_manager_add_ui_from_string(manager, file_ui, -1,
						  &error);
	else
		gtk_ui_manager_add_ui_from_string(manager, note_file_ui,
						  -1, &error);

	handle_error(&error);

	gtk_ui_manager_add_ui_from_string(manager, view_ui, -1, &error);
	handle_error(&error);

	if (e->type == STUDYPAD_EDITOR)
		gtk_ui_manager_add_ui_from_string(manager,
						  main_ui_studypad, -1,
						  &error);
	else
		gtk_ui_manager_add_ui_from_string(manager, main_ui_note,
						  -1, &error);

	handle_error(&error);

	action_group = gtk_action_group_new("file");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, file_entries,
				     G_N_ELEMENTS(file_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("view");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, view_entries,
				     G_N_ELEMENTS(view_entries), editor);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("main");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, main_entries,
				     G_N_ELEMENTS(main_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("context-menu");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, test_entries,
				     G_N_ELEMENTS(test_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	gtk_ui_manager_ensure_update(manager);
	gtk_widget_show(editor);

	gtkhtml_editor_drop_undo(GTKHTML_EDITOR(e->window));
	gtkhtml_editor_set_changed(GTKHTML_EDITOR(e->window), FALSE);

	g_signal_connect(editor, "delete-event",
			 G_CALLBACK(app_delete_cb), (EDITOR *)e);
	return editor;
}
예제 #2
0
/* Helper for gtkhtml_editor_update_context() */
static void
editor_spell_checkers_foreach (GtkhtmlSpellChecker *checker,
                               GtkhtmlEditor *editor)
{
	const GtkhtmlSpellLanguage *language;
	const gchar *language_code;
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkHTML *html;
	GList *list;
	gchar *path;
	gchar *word;
	gint count = 0;
	guint merge_id;

	language = gtkhtml_spell_checker_get_language (checker);
	language_code = gtkhtml_spell_language_get_code (language);

	html = gtkhtml_editor_get_html (editor);
	word = html_engine_get_spell_word (html->engine);
	list = gtkhtml_spell_checker_get_suggestions (checker, word, -1);

	manager = gtkhtml_editor_get_ui_manager (editor);
	action_group = editor->priv->suggestion_actions;
	merge_id = editor->priv->spell_suggestions_merge_id;

	path = g_strdup_printf (
		"/context-menu/context-spell-suggest/"
		"context-spell-suggest-%s-menu", language_code);

	while (list != NULL) {
		gchar *suggestion = list->data;
		gchar *action_name;
		gchar *action_label;
		GtkAction *action;
		GtkWidget *child;
		GSList *proxies;

		/* Action name just needs to be unique. */
		action_name = g_strdup_printf (
			"suggest-%s-%d", language_code, count++);

		action_label = g_markup_printf_escaped (
			"<b>%s</b>", suggestion);

		action = gtk_action_new (
			action_name, action_label, NULL, NULL);

		g_object_set_data_full (
			G_OBJECT (action), "word",
			g_strdup (suggestion), g_free);

		g_signal_connect (
			action, "activate", G_CALLBACK (
			action_context_spell_suggest_cb), editor);

		gtk_action_group_add_action (action_group, action);

		gtk_ui_manager_add_ui (
			manager, merge_id, path,
			action_name, action_name,
			GTK_UI_MANAGER_AUTO, FALSE);

		/* XXX GtkAction offers no supports for Pango markup,
		 *     so we have to manually set "use-markup" on the
		 *     child of the proxy widget. */
		gtk_ui_manager_ensure_update (manager);
		proxies = gtk_action_get_proxies (action);
		child = gtk_bin_get_child (proxies->data);
		g_object_set (child, "use-markup", TRUE, NULL);

		g_free (suggestion);
		g_free (action_name);
		g_free (action_label);

		list = g_list_delete_link (list, list);
	}

	g_free (path);
	g_free (word);
}
예제 #3
0
void
gtkhtml_editor_update_context (GtkhtmlEditor *editor)
{
	GtkHTML *html;
	HTMLType type;
	HTMLObject *object;
	GtkUIManager *manager;
	GtkActionGroup *action_group;
	GList *list;
	gboolean visible;
	guint merge_id;

	html = gtkhtml_editor_get_html (editor);
	manager = gtkhtml_editor_get_ui_manager (editor);
	gtk_html_update_styles (html);

	/* Update context menu item visibility. */

	object = html->engine->cursor->object;

	if (object != NULL)
		type = HTML_OBJECT_TYPE (object);
	else
		type = HTML_TYPE_NONE;

	visible = (type == HTML_TYPE_IMAGE);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_IMAGE), visible);

	visible = (type == HTML_TYPE_LINKTEXT);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_LINK), visible);

	visible = (type == HTML_TYPE_RULE);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_RULE), visible);

	visible = (type == HTML_TYPE_TEXT);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_TEXT), visible);

	visible =
		gtk_action_get_visible (ACTION (CONTEXT_PROPERTIES_IMAGE)) ||
		gtk_action_get_visible (ACTION (CONTEXT_PROPERTIES_LINK)) ||
		gtk_action_get_visible (ACTION (CONTEXT_PROPERTIES_TEXT));
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_PARAGRAPH), visible);

	/* Set to visible if any of these are true:
	 *   - Selection is active and contains a link.
	 *   - Cursor is on a link.
	 *   - Cursor is on an image that has a URL or target.
	 */
	visible =
		(html_engine_is_selection_active (html->engine) &&
		 html_engine_selection_contains_link (html->engine)) ||
		(type == HTML_TYPE_LINKTEXT) ||
		(type == HTML_TYPE_IMAGE &&
			(HTML_IMAGE (object)->url != NULL ||
			 HTML_IMAGE (object)->target != NULL));
	gtk_action_set_visible (ACTION (CONTEXT_REMOVE_LINK), visible);

	/* Get the parent object. */
	object = (object != NULL) ? object->parent : NULL;

	/* Get the grandparent object. */
	object = (object != NULL) ? object->parent : NULL;

	if (object != NULL)
		type = HTML_OBJECT_TYPE (object);
	else
		type = HTML_TYPE_NONE;

	visible = (type == HTML_TYPE_TABLECELL);
	gtk_action_set_visible (ACTION (CONTEXT_DELETE_CELL), visible);
	gtk_action_set_visible (ACTION (CONTEXT_DELETE_COLUMN), visible);
	gtk_action_set_visible (ACTION (CONTEXT_DELETE_ROW), visible);
	gtk_action_set_visible (ACTION (CONTEXT_DELETE_TABLE), visible);
	gtk_action_set_visible (ACTION (CONTEXT_INSERT_COLUMN_AFTER), visible);
	gtk_action_set_visible (ACTION (CONTEXT_INSERT_COLUMN_BEFORE), visible);
	gtk_action_set_visible (ACTION (CONTEXT_INSERT_ROW_ABOVE), visible);
	gtk_action_set_visible (ACTION (CONTEXT_INSERT_ROW_BELOW), visible);
	gtk_action_set_visible (ACTION (CONTEXT_INSERT_TABLE), visible);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_CELL), visible);

	/* Get the great grandparent object. */
	object = (object != NULL) ? object->parent : NULL;

	if (object != NULL)
		type = HTML_OBJECT_TYPE (object);
	else
		type = HTML_TYPE_NONE;

	/* Note the |= (cursor must be in a table cell). */
	visible |= (type == HTML_TYPE_TABLE);
	gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_TABLE), visible);

	/********************** Spell Check Suggestions **********************/

	object = html->engine->cursor->object;
	action_group = editor->priv->suggestion_actions;

	/* Remove the old content from the context menu. */
	merge_id = editor->priv->spell_suggestions_merge_id;
	if (merge_id > 0) {
		gtk_ui_manager_remove_ui (manager, merge_id);
		editor->priv->spell_suggestions_merge_id = 0;
	}

	/* Clear the action group for spelling suggestions. */
	list = gtk_action_group_list_actions (action_group);
	while (list != NULL) {
		GtkAction *action = list->data;

		gtk_action_group_remove_action (action_group, action);
		list = g_list_delete_link (list, list);
	}

	/* Decide if we should show spell checking items. */
	visible =
		!html_engine_is_selection_active (html->engine) &&
		object != NULL && html_object_is_text (object) &&
		!html_engine_spell_word_is_valid (html->engine);
	action_group = editor->priv->spell_check_actions;
	gtk_action_group_set_visible (action_group, visible);

	/* Exit early if spell checking items are invisible. */
	if (!visible)
		return;

	list = editor->priv->active_spell_checkers;
	merge_id = gtk_ui_manager_new_merge_id (manager);
	editor->priv->spell_suggestions_merge_id = merge_id;

	/* Handle a single active language as a special case. */
	if (g_list_length (list) == 1) {
		editor_inline_spelling_suggestions (editor, list->data);
		return;
	}

	/* Add actions and context menu content for active languages. */
	g_list_foreach (list, (GFunc) editor_spell_checkers_foreach, editor);
}
예제 #4
0
static void
editor_inline_spelling_suggestions (GtkhtmlEditor *editor,
                                    GtkhtmlSpellChecker *checker)
{
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkHTML *html;
	GList *list;
	const gchar *path;
	gchar *word;
	guint count = 0;
	guint length;
	guint merge_id;
	guint threshold;

	html = gtkhtml_editor_get_html (editor);
	word = html_engine_get_spell_word (html->engine);
	list = gtkhtml_spell_checker_get_suggestions (checker, word, -1);

	path = "/context-menu/context-spell-suggest/";
	manager = gtkhtml_editor_get_ui_manager (editor);
	action_group = editor->priv->suggestion_actions;
	merge_id = editor->priv->spell_suggestions_merge_id;

	/* Calculate how many suggestions to put directly in the
	 * context menu.  The rest will go in a secondary menu. */
	length = g_list_length (list);
	if (length <= MAX_LEVEL1_SUGGESTIONS)
		threshold = length;
	else if (length - MAX_LEVEL1_SUGGESTIONS < MIN_LEVEL2_SUGGESTIONS)
		threshold = length;
	else
		threshold = MAX_LEVEL1_SUGGESTIONS;

	while (list != NULL) {
		gchar *suggestion = list->data;
		gchar *action_name;
		gchar *action_label;
		GtkAction *action;
		GtkWidget *child;
		GSList *proxies;

		/* Once we reach the threshold, put all subsequent
		 * spelling suggestions in a secondary menu. */
		if (count == threshold)
			path = "/context-menu/context-more-suggestions-menu/";

		/* Action name just needs to be unique. */
		action_name = g_strdup_printf ("suggest-%d", count++);

		action_label = g_markup_printf_escaped (
			"<b>%s</b>", suggestion);

		action = gtk_action_new (
			action_name, action_label, NULL, NULL);

		g_object_set_data_full (
			G_OBJECT (action), "word",
			g_strdup (suggestion), g_free);

		g_signal_connect (
			action, "activate", G_CALLBACK (
			action_context_spell_suggest_cb), editor);

		gtk_action_group_add_action (action_group, action);

		gtk_ui_manager_add_ui (
			manager, merge_id, path,
			action_name, action_name,
			GTK_UI_MANAGER_AUTO, FALSE);

		/* XXX GtkAction offers no support for Pango markup,
		 *     so we have to manually set "use-markup" on the
		 *     child of the proxy widget. */
		gtk_ui_manager_ensure_update (manager);
		proxies = gtk_action_get_proxies (action);
		child = gtk_bin_get_child (proxies->data);
		g_object_set (child, "use-markup", TRUE, NULL);

		g_free (suggestion);
		g_free (action_name);
		g_free (action_label);

		list = g_list_delete_link (list, list);
	}

	g_free (word);
}