summaryrefslogtreecommitdiffstats
path: root/src/widgets/ink-comboboxentry-action.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/ink-comboboxentry-action.cpp')
-rw-r--r--src/widgets/ink-comboboxentry-action.cpp964
1 files changed, 0 insertions, 964 deletions
diff --git a/src/widgets/ink-comboboxentry-action.cpp b/src/widgets/ink-comboboxentry-action.cpp
deleted file mode 100644
index a49d5c2c3..000000000
--- a/src/widgets/ink-comboboxentry-action.cpp
+++ /dev/null
@@ -1,964 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * A subclass of GtkAction that wraps a GtkComboBoxEntry.
- * Features:
- * Setting GtkEntryBox width in characters.
- * Passing a function for formatting cells.
- * Displaying a warning if entry text isn't in list.
- * Check comma separated values in text against list. (Useful for font-family fallbacks.)
- * Setting names for GtkComboBoxEntry and GtkEntry (actionName_combobox, actionName_entry)
- * to allow setting resources.
- *
- * Author(s):
- * Tavmjong Bah
- * Jon A. Cruz <jon@joncruz.org>
- *
- * Copyright (C) 2010 Authors
- *
- * Released under GNU GPL v2+, read the file 'COPYING' for more information.
- */
-
-/*
- * We must provide for both a toolbar item and a menu item.
- * As we don't know which widgets are used (or even constructed),
- * we must keep track of things like active entry ourselves.
- */
-
-#include <iostream>
-#include <cstring>
-#include <glibmm/ustring.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdkmm/display.h>
-
-#include "widgets/ink-comboboxentry-action.h"
-#include "ui/icon-names.h"
-
-// Must handle both tool and menu items!
-static GtkWidget* create_tool_item( GtkAction* action );
-static GtkWidget* create_menu_item( GtkAction* action );
-
-// Internal
-static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false, gboolean ignore_case = false );
-static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action );
-
-// Callbacks
-static void combo_box_changed_cb( GtkComboBox* widget, gpointer data );
-static void entry_activate_cb( GtkEntry* widget, gpointer data );
-static gboolean match_selected_cb( GtkEntryCompletion* widget, GtkTreeModel* model, GtkTreeIter* iter, gpointer data );
-static gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data );
-
-enum {
- PROP_MODEL = 1,
- PROP_COMBOBOX,
- PROP_ENTRY,
- PROP_ENTRY_WIDTH,
- PROP_EXTRA_WIDTH,
- PROP_CELL_DATA_FUNC,
- PROP_SEPARATOR_FUNC,
- PROP_POPUP,
- PROP_FOCUS_WIDGET
-};
-
-enum {
- CHANGED = 0,
- ACTIVATED,
- N_SIGNALS
-};
-static guint signals[N_SIGNALS] = {0};
-
-static GQuark gDataName = 0;
-
-static void ink_comboboxentry_action_init (Ink_ComboBoxEntry_Action *action);
-static void ink_comboboxentry_action_class_init (Ink_ComboBoxEntry_ActionClass *klass);
-
-G_DEFINE_TYPE(Ink_ComboBoxEntry_Action, ink_comboboxentry_action, GTK_TYPE_ACTION);
-
-static void ink_comboboxentry_action_finalize (GObject *object)
-{
- // Free any allocated resources.
-
- G_OBJECT_CLASS (ink_comboboxentry_action_parent_class)->finalize (object);
-}
-
-
-static void ink_comboboxentry_action_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION (object);
-
- switch(property_id) {
-
- case PROP_MODEL:
- action->model = GTK_TREE_MODEL( g_value_get_object( value ));
- break;
-
- case PROP_COMBOBOX:
- action->combobox = GTK_COMBO_BOX (g_value_get_object (value));
- break;
-
- case PROP_ENTRY:
- action->entry = GTK_ENTRY( g_value_get_object( value ));
- break;
-
- case PROP_ENTRY_WIDTH:
- action->entry_width = g_value_get_int( value );
- break;
-
- case PROP_EXTRA_WIDTH:
- action->extra_width = g_value_get_int( value );
- break;
-
- case PROP_CELL_DATA_FUNC:
- action->cell_data_func = g_value_get_pointer( value );
- break;
-
- case PROP_SEPARATOR_FUNC:
- action->separator_func = g_value_get_pointer( value );
- break;
-
- case PROP_POPUP:
- action->popup = g_value_get_boolean( value );
- break;
-
- case PROP_FOCUS_WIDGET:
- action->focusWidget = (GtkWidget*)g_value_get_pointer( value );
- break;
-
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-
-static void ink_comboboxentry_action_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION (object);
-
- switch(property_id) {
-
- case PROP_MODEL:
- g_value_set_object (value, action->model);
- break;
-
- case PROP_COMBOBOX:
- g_value_set_object (value, action->combobox);
- break;
-
- case PROP_ENTRY:
- g_value_set_object (value, action->entry);
- break;
-
- case PROP_ENTRY_WIDTH:
- g_value_set_int (value, action->entry_width);
- break;
-
- case PROP_EXTRA_WIDTH:
- g_value_set_int (value, action->extra_width);
- break;
-
- case PROP_CELL_DATA_FUNC:
- g_value_set_pointer (value, action->cell_data_func);
- break;
-
- case PROP_SEPARATOR_FUNC:
- g_value_set_pointer (value, action->separator_func);
- break;
-
- case PROP_POPUP:
- g_value_set_boolean (value, action->popup);
- break;
-
- case PROP_FOCUS_WIDGET:
- g_value_set_pointer (value, action->focusWidget);
- break;
-
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-ink_comboboxentry_action_connect_proxy (GtkAction *action,
- GtkWidget *proxy)
-{
- /* Override any proxy properties. */
- // if (GTK_IS_MENU_ITEM (proxy)) {
- // }
-
- GTK_ACTION_CLASS (ink_comboboxentry_action_parent_class)->connect_proxy (action, proxy);
-}
-
-static void
-ink_comboboxentry_action_class_init (Ink_ComboBoxEntry_ActionClass *klass)
-{
-
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkActionClass *gtkaction_class = GTK_ACTION_CLASS (klass);
-
- gtkaction_class->connect_proxy = ink_comboboxentry_action_connect_proxy;
-
- gobject_class->finalize = ink_comboboxentry_action_finalize;
- gobject_class->set_property = ink_comboboxentry_action_set_property;
- gobject_class->get_property = ink_comboboxentry_action_get_property;
-
- gDataName = g_quark_from_string("ink_comboboxentry-action");
-
- klass->parent_class.create_tool_item = create_tool_item;
- klass->parent_class.create_menu_item = create_menu_item;
-
- g_object_class_install_property (
- gobject_class,
- PROP_MODEL,
- g_param_spec_object ("model",
- "Tree Model",
- "Tree Model",
- GTK_TYPE_TREE_MODEL,
- (GParamFlags)G_PARAM_READWRITE));
- g_object_class_install_property (
- gobject_class,
- PROP_COMBOBOX,
- g_param_spec_object ("combobox",
- "GtkComboBoxEntry",
- "GtkComboBoxEntry",
- GTK_TYPE_WIDGET,
- (GParamFlags)G_PARAM_READABLE));
- g_object_class_install_property (
- gobject_class,
- PROP_ENTRY,
- g_param_spec_object ("entry",
- "GtkEntry",
- "GtkEntry",
- GTK_TYPE_WIDGET,
- (GParamFlags)G_PARAM_READABLE));
- g_object_class_install_property (
- gobject_class,
- PROP_ENTRY_WIDTH,
- g_param_spec_int ("entry_width",
- "EntryBox width",
- "EntryBox width (characters)",
- -1.0, 100, -1.0,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property (
- gobject_class,
- PROP_EXTRA_WIDTH,
- g_param_spec_int ("extra_width",
- "Extra width",
- "Extra width (px)",
- -1.0, 500, -1.0,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property (
- gobject_class,
- PROP_CELL_DATA_FUNC,
- g_param_spec_pointer ("cell_data_func",
- "Cell Data Func",
- "Cell Deta Function",
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property (
- gobject_class,
- PROP_SEPARATOR_FUNC,
- g_param_spec_pointer ("separator_func",
- "Separator Func",
- "Separator Function",
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property (
- gobject_class,
- PROP_POPUP,
- g_param_spec_boolean ("popup",
- "Entry Popup",
- "Entry Popup",
- false,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property( gobject_class,
- PROP_FOCUS_WIDGET,
- g_param_spec_pointer( "focus-widget",
- "Focus Widget",
- "The widget to return focus to",
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
-
- // We need to know when GtkComboBoxEvent or Menu ready for reading
- signals[CHANGED] = g_signal_new( "changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(Ink_ComboBoxEntry_ActionClass, changed),
- nullptr, nullptr,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- // Probably not needed... originally to keep track of key-presses.
- signals[ACTIVATED] = g_signal_new( "activated",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(Ink_ComboBoxEntry_ActionClass, activated),
- nullptr, nullptr,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
-}
-
-static void ink_comboboxentry_action_init (Ink_ComboBoxEntry_Action *action)
-{
- action->active = -1;
- action->text = strdup("");
- action->entry_completion = nullptr;
- action->indicator = nullptr;
- action->popup = false;
- action->info = nullptr;
- action->info_cb = nullptr;
- action->info_cb_id = 0;
- action->info_cb_blocked = false;
- action->warning = nullptr;
- action->warning_cb = nullptr;
- action->warning_cb_id = 0;
- action->warning_cb_blocked = false;
- action->altx_name = nullptr;
- action->focusWidget = nullptr;
-}
-
-Ink_ComboBoxEntry_Action *ink_comboboxentry_action_new (const gchar *name,
- const gchar *label,
- const gchar *tooltip,
- const gchar *stock_id,
- GtkTreeModel *model,
- gint entry_width,
- gint extra_width,
- void *cell_data_func,
- void *separator_func,
- GtkWidget *focusWidget)
-{
- g_return_val_if_fail (name != nullptr, NULL);
-
- return (Ink_ComboBoxEntry_Action*)g_object_new (INK_COMBOBOXENTRY_TYPE_ACTION,
- "name", name,
- "label", label,
- "tooltip", tooltip,
- "stock-id", stock_id,
- "model", model,
- "entry_width", entry_width,
- "extra_width", extra_width,
- "cell_data_func", cell_data_func,
- "separator_func", separator_func,
- "focus-widget", focusWidget,
- NULL);
-}
-
-// Create a widget for a toolbar.
-GtkWidget* create_tool_item( GtkAction* action )
-{
- GtkWidget* item = nullptr;
-
- if ( INK_COMBOBOXENTRY_IS_ACTION( action ) && INK_COMBOBOXENTRY_ACTION(action)->model ) {
-
- Ink_ComboBoxEntry_Action* ink_comboboxentry_action = INK_COMBOBOXENTRY_ACTION( action );
-
- gchar *action_name = g_strdup( gtk_action_get_name( action ) );
- gchar *combobox_name = g_strjoin( nullptr, action_name, "_combobox", NULL );
- gchar *entry_name = g_strjoin( nullptr, action_name, "_entry", NULL );
- g_free( action_name );
-
- item = GTK_WIDGET( gtk_tool_item_new() );
-
- GtkWidget* comboBoxEntry = gtk_combo_box_new_with_model_and_entry (ink_comboboxentry_action->model);
- gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (comboBoxEntry), 0);
-
- // Name it so we can muck with it using an RC file
- gtk_widget_set_name( comboBoxEntry, combobox_name );
- g_free( combobox_name );
-
- {
- gtk_widget_set_halign(comboBoxEntry, GTK_ALIGN_START);
- gtk_widget_set_hexpand(comboBoxEntry, FALSE);
- gtk_widget_set_vexpand(comboBoxEntry, FALSE);
- gtk_container_add(GTK_CONTAINER(item), comboBoxEntry);
- }
-
- ink_comboboxentry_action->combobox = GTK_COMBO_BOX (comboBoxEntry);
-
- //gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), ink_comboboxentry_action->active );
- gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), 0 );
-
- g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action );
-
- // Optionally add separator function...
- if( ink_comboboxentry_action->separator_func != nullptr ) {
- gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
- GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
- nullptr, nullptr );
- }
-
- // FIXME: once gtk3 migration is done this can be removed
- // https://bugzilla.gnome.org/show_bug.cgi?id=734915
- gtk_widget_show_all (comboBoxEntry);
-
- // Optionally add formatting...
- if( ink_comboboxentry_action->cell_data_func != nullptr ) {
- GtkCellRenderer *cell = gtk_cell_renderer_text_new();
- gtk_cell_layout_clear( GTK_CELL_LAYOUT( comboBoxEntry ) );
- gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( comboBoxEntry ), cell, true );
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT( comboBoxEntry ), cell,
- GtkCellLayoutDataFunc (ink_comboboxentry_action->cell_data_func),
- nullptr, nullptr );
- }
-
- // Optionally widen the combobox width... which widens the drop-down list in list mode.
- if( ink_comboboxentry_action->extra_width > 0 ) {
- GtkRequisition req;
- gtk_widget_get_preferred_size(GTK_WIDGET(ink_comboboxentry_action->combobox), &req, nullptr);
- gtk_widget_set_size_request( GTK_WIDGET( ink_comboboxentry_action->combobox ),
- req.width + ink_comboboxentry_action->extra_width, -1 );
- }
-
- // Get reference to GtkEntry and fiddle a bit with it.
- GtkWidget *child = gtk_bin_get_child( GTK_BIN(comboBoxEntry) );
-
- // Name it so we can muck with it using an RC file
- gtk_widget_set_name( child, entry_name );
- g_free( entry_name );
-
- if( child && GTK_IS_ENTRY( child ) ) {
-
- ink_comboboxentry_action->entry = GTK_ENTRY(child);
-
- // Change width
- if( ink_comboboxentry_action->entry_width > 0 ) {
- gtk_entry_set_width_chars (GTK_ENTRY (child), ink_comboboxentry_action->entry_width );
- }
-
- // Add pop-up entry completion if required
- if( ink_comboboxentry_action->popup ) {
- ink_comboboxentry_action_popup_enable( ink_comboboxentry_action );
- }
-
- // Add altx_name if required
- if( ink_comboboxentry_action->altx_name ) {
- g_object_set_data( G_OBJECT( child ), ink_comboboxentry_action->altx_name, ink_comboboxentry_action->entry );
- }
-
- // Add signal for GtkEntry to check if finished typing.
- g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(entry_activate_cb), action );
- g_signal_connect( G_OBJECT(child), "key-press-event", G_CALLBACK(keypress_cb), action );
- }
-
- gtk_activatable_set_related_action( GTK_ACTIVATABLE (item), GTK_ACTION( action ) );
- gtk_widget_show_all( item );
-
- } else {
-
- item = GTK_ACTION_CLASS(ink_comboboxentry_action_parent_class)->create_tool_item( action );
-
- }
-
- return item;
-}
-
-// Create a drop-down menu.
-GtkWidget* create_menu_item( GtkAction* action )
-{
- GtkWidget* item = nullptr;
-
- item = GTK_ACTION_CLASS(ink_comboboxentry_action_parent_class)->create_menu_item( action );
- g_warning( "ink_comboboxentry_action: create_menu_item not implemented" );
- // One can easily modify ege-select-one-action routine to implement this.
- return item;
-}
-
-// Setters/Getters ---------------------------------------------------
-
-GtkTreeModel *ink_comboboxentry_action_get_model( Ink_ComboBoxEntry_Action* action ) {
-
- return action->model;
-}
-
-GtkComboBox *ink_comboboxentry_action_get_comboboxentry( Ink_ComboBoxEntry_Action* action ) {
-
- return action->combobox;
-}
-
-gchar* ink_comboboxentry_action_get_active_text( Ink_ComboBoxEntry_Action* action ) {
-
- gchar* text = g_strdup( action->text );
- return text;
-}
-
-/*
- * For the font-family list we need to handle two cases:
- * Text is in list store:
- * In this case we use row number as the font-family list can have duplicate
- * entries, one in the document font part and one in the system font part. In
- * order that scrolling through the list works properly we must distinguish
- * between the two.
- * Text is not in the list store (i.e. default font-family is not on system):
- * In this case we have a row number of -1, and the text must be set by hand.
- */
-gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text, int row ) {
-
- if( strcmp( action->text, text ) != 0 ) {
- g_free( action->text );
- action->text = g_strdup( text );
- }
-
- // Get active row or -1 if none
- if( row < 0 ) {
- row = get_active_row_from_text( action, action->text );
- }
- action->active = row;
-
- // Set active row, check that combobox has been created.
- if( action->combobox ) {
- gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox ), action->active );
- }
-
- // Fiddle with entry
- if( action->entry ) {
-
- // Explicitly set text in GtkEntry box (won't be set if text not in list).
- gtk_entry_set_text( action->entry, text );
-
- // Show or hide warning -- this might be better moved to text-toolbox.cpp
- if( action->info_cb_id != 0 &&
- !action->info_cb_blocked ) {
- g_signal_handler_block (G_OBJECT(action->entry),
- action->info_cb_id );
- action->info_cb_blocked = true;
- }
- if( action->warning_cb_id != 0 &&
- !action->warning_cb_blocked ) {
- g_signal_handler_block (G_OBJECT(action->entry),
- action->warning_cb_id );
- action->warning_cb_blocked = true;
- }
-
- bool set = false;
- if( action->warning != nullptr ) {
- Glib::ustring missing = check_comma_separated_text( action );
- if( !missing.empty() ) {
- gtk_entry_set_icon_from_icon_name( action->entry,
- GTK_ENTRY_ICON_SECONDARY,
- INKSCAPE_ICON("dialog-warning") );
- // Can't add tooltip until icon set
- Glib::ustring warning = action->warning;
- warning += ": ";
- warning += missing;
- gtk_entry_set_icon_tooltip_text( action->entry,
- GTK_ENTRY_ICON_SECONDARY,
- warning.c_str() );
-
- if( action->warning_cb ) {
-
- // Add callback if we haven't already
- if( action->warning_cb_id == 0 ) {
- action->warning_cb_id =
- g_signal_connect( G_OBJECT(action->entry),
- "icon-press",
- G_CALLBACK(action->warning_cb),
- action);
- }
- // Unblock signal
- if( action->warning_cb_blocked ) {
- g_signal_handler_unblock (G_OBJECT(action->entry),
- action->warning_cb_id );
- action->warning_cb_blocked = false;
- }
- }
- set = true;
- }
- }
-
- if( !set && action->info != nullptr ) {
- gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry),
- GTK_ENTRY_ICON_SECONDARY,
- INKSCAPE_ICON("edit-select-all") );
- gtk_entry_set_icon_tooltip_text( action->entry,
- GTK_ENTRY_ICON_SECONDARY,
- action->info );
-
- if( action->info_cb ) {
- // Add callback if we haven't already
- if( action->info_cb_id == 0 ) {
- action->info_cb_id =
- g_signal_connect( G_OBJECT(action->entry),
- "icon-press",
- G_CALLBACK(action->info_cb),
- action);
- }
- // Unblock signal
- if( action->info_cb_blocked ) {
- g_signal_handler_unblock (G_OBJECT(action->entry),
- action->info_cb_id );
- action->info_cb_blocked = false;
- }
- }
- set = true;
- }
-
- if( !set ) {
- gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry),
- GTK_ENTRY_ICON_SECONDARY,
- nullptr );
- }
- }
-
- // Return if active text in list
- gboolean found = ( action->active != -1 );
- return found;
-}
-
-void ink_comboboxentry_action_set_entry_width( Ink_ComboBoxEntry_Action* action, gint entry_width ) {
-
- action->entry_width = entry_width;
-
- // Widget may not have been created....
- if( action->entry ) {
- gtk_entry_set_width_chars( GTK_ENTRY(action->entry), entry_width );
- }
-}
-
-void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, gint extra_width ) {
-
- action->extra_width = extra_width;
-
- // Widget may not have been created....
- if( action->combobox ) {
- GtkRequisition req;
- gtk_widget_get_preferred_size(GTK_WIDGET(action->combobox), &req, nullptr);
- gtk_widget_set_size_request( GTK_WIDGET( action->combobox ), req.width + action->extra_width, -1 );
- }
-}
-
-void ink_comboboxentry_action_popup_enable( Ink_ComboBoxEntry_Action* action ) {
-
- action->popup = true;
-
- // Widget may not have been created....
- if( action->entry ) {
-
- // Check we don't already have a GtkEntryCompletion
- if( action->entry_completion ) return;
-
- action->entry_completion = gtk_entry_completion_new();
-
- gtk_entry_set_completion( action->entry, action->entry_completion );
- gtk_entry_completion_set_model( action->entry_completion, action->model );
- gtk_entry_completion_set_text_column( action->entry_completion, 0 );
- gtk_entry_completion_set_popup_completion( action->entry_completion, true );
- gtk_entry_completion_set_inline_completion( action->entry_completion, false );
- gtk_entry_completion_set_inline_selection( action->entry_completion, true );
-
- g_signal_connect (G_OBJECT (action->entry_completion), "match-selected", G_CALLBACK (match_selected_cb), action );
-
-
- }
-}
-
-void ink_comboboxentry_action_popup_disable( Ink_ComboBoxEntry_Action* action ) {
-
- action->popup = false;
-
- if( action->entry_completion ) {
- gtk_widget_destroy(GTK_WIDGET(action->entry_completion));
- action->entry_completion = nullptr;
- }
-}
-void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip ) {
-
- // Widget may not have been created....
- if( action->entry ) {
- gtk_widget_set_tooltip_text ( GTK_WIDGET(action->entry), tooltip);
- }
- if( action->combobox ) {
- gtk_widget_set_tooltip_text ( GTK_WIDGET(action->combobox), tooltip);
- }
-
-}
-
-void ink_comboboxentry_action_set_info( Ink_ComboBoxEntry_Action* action, const gchar* info ) {
-
- g_free( action->info );
- action->info = g_strdup( info );
-
- // Widget may not have been created....
- if( action->entry ) {
- gtk_entry_set_icon_tooltip_text( GTK_ENTRY(action->entry),
- GTK_ENTRY_ICON_SECONDARY,
- action->info );
- }
-}
-
-void ink_comboboxentry_action_set_info_cb( Ink_ComboBoxEntry_Action* action, gpointer info_cb ) {
-
- action->info_cb = info_cb;
-}
-
-void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning ) {
-
- g_free( action->warning );
- action->warning = g_strdup( warning );
-
- // Widget may not have been created....
- if( action->entry ) {
- gtk_entry_set_icon_tooltip_text( GTK_ENTRY(action->entry),
- GTK_ENTRY_ICON_SECONDARY,
- action->warning );
- }
-}
-
-void ink_comboboxentry_action_set_warning_cb( Ink_ComboBoxEntry_Action* action, gpointer warning_cb ) {
-
- action->warning_cb = warning_cb;
-}
-
-void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name ) {
-
- g_free( action->altx_name );
- action->altx_name = g_strdup( altx_name );
-
- // Widget may not have been created....
- if( action->entry ) {
- g_object_set_data( G_OBJECT(action->entry), action->altx_name, action->entry );
- }
-}
-
-// Internal ---------------------------------------------------
-
-// Return row of active text or -1 if not found. If exclude is true,
-// use 3d colunm if available to exclude row from checking (useful to
-// skip rows added for font-families included in doc and not on
-// system)
-gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text,
- gboolean exclude, gboolean ignore_case ) {
-
- // Check if text in list
- gint row = 0;
- gboolean found = false;
- GtkTreeIter iter;
- gboolean valid = gtk_tree_model_get_iter_first( action->model, &iter );
- while ( valid ) {
-
- // See if we should exclude a row
- gboolean check = true; // If true, font-family is on system.
- if( exclude && gtk_tree_model_get_n_columns( action->model ) > 2 ) {
- gtk_tree_model_get( action->model, &iter, 2, &check, -1 );
- }
-
- if( check ) {
- // Get text from list entry
- gchar* text = nullptr;
- gtk_tree_model_get( action->model, &iter, 0, &text, -1 ); // Column 0
-
- if( !ignore_case ) {
- // Case sensitive compare
- if( strcmp( target_text, text ) == 0 ){
- found = true;
- break;
- }
- } else {
- // Case insensitive compare
- gchar* target_text_casefolded = g_utf8_casefold( target_text, -1 );
- gchar* text_casefolded = g_utf8_casefold( text, -1 );
- gboolean equal = (strcmp( target_text_casefolded, text_casefolded ) == 0 );
- g_free( text_casefolded );
- g_free( target_text_casefolded );
- if( equal ) {
- found = true;
- break;
- }
- }
- }
-
- ++row;
- valid = gtk_tree_model_iter_next( action->model, &iter );
- }
-
- if( !found ) row = -1;
-
- return row;
-
-}
-
-// Checks if all comma separated text fragments are in the list and
-// returns a ustring with a list of missing fragments.
-// This is useful for checking if all fonts in a font-family fallback
-// list are available on the system.
-//
-// This routine could also create a Pango Markup string to show which
-// fragments are invalid in the entry box itself. See:
-// http://developer.gnome.org/pango/stable/PangoMarkupFormat.html
-// However... it appears that while one can retrieve the PangoLayout
-// for a GtkEntry box, it is only a copy and changing it has no effect.
-// PangoLayout * pl = gtk_entry_get_layout( entry );
-// pango_layout_set_markup( pl, "NEW STRING", -1 ); // DOESN'T WORK
-static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action ) {
-
- Glib::ustring missing;
-
- // Parse fallback_list using a comma as deliminator
- gchar** tokens = g_strsplit( action->text, ",", 0 );
-
- gint i = 0;
- while( tokens[i] != nullptr ) {
-
- // Remove any surrounding white space.
- g_strstrip( tokens[i] );
-
- if( get_active_row_from_text( action, tokens[i], true, true ) == -1 ) {
- missing += tokens[i];
- missing += ", ";
- }
- ++i;
- }
- g_strfreev( tokens );
-
- // Remove extra comma and space from end.
- if( missing.size() >= 2 ) {
- missing.resize( missing.size()-2 );
- }
- return missing;
-}
-
-// Callbacks ---------------------------------------------------
-
-static void combo_box_changed_cb( GtkComboBox* widget, gpointer data ) {
-
- // Two things can happen to get here:
- // An item is selected in the drop-down menu.
- // Text is typed.
- // We only react here if an item is selected.
-
- // Get action
- Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
-
- // Check if item selected:
- gint newActive = gtk_combo_box_get_active(widget);
- if( newActive >= 0 && newActive != action->active ) {
-
- action->active = newActive;
-
- GtkTreeIter iter;
- if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX( action->combobox ), &iter ) ) {
-
- gchar* text = nullptr;
- gtk_tree_model_get( action->model, &iter, 0, &text, -1 );
- gtk_entry_set_text( action->entry, text );
-
- g_free( action->text );
- action->text = text;
- }
-
- // Now let the world know
- g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
- }
-}
-
-static void entry_activate_cb( GtkEntry* widget, gpointer data ) {
-
- // Get text from entry box.. check if it matches a menu entry.
-
- // Get action
- Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
-
- // Get text
- g_free( action->text );
- action->text = g_strdup( gtk_entry_get_text( widget ) );
-
- // Get row
- action->active =
- get_active_row_from_text( action, action->text );
-
- // Set active row
- gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active );
-
- // Now let the world know
- g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
-
-}
-
-static gboolean match_selected_cb( GtkEntryCompletion* /*widget*/, GtkTreeModel* model, GtkTreeIter* iter, gpointer data )
-{
- // Get action
- Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
- GtkEntry *entry = action->entry;
-
- if( entry) {
- gchar *family = nullptr;
- gtk_tree_model_get(model, iter, 0, &family, -1);
-
- // Set text in GtkEntry
- gtk_entry_set_text (GTK_ENTRY (entry), family );
-
- // Set text in GtkAction
- g_free( action->text );
- action->text = family;
-
- // Get row
- action->active =
- get_active_row_from_text( action, action->text );
-
- // Set active row
- gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active );
-
- // Now let the world know
- g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
-
- return true;
- }
- return false;
-}
-
-static void ink_comboboxentry_action_defocus( Ink_ComboBoxEntry_Action* action )
-{
- if ( action->focusWidget ) {
- gtk_widget_grab_focus( action->focusWidget );
- }
-}
-
-gboolean keypress_cb( GtkWidget * /*widget*/, GdkEventKey *event, gpointer data )
-{
- gboolean wasConsumed = FALSE; /* default to report event not consumed */
- guint key = 0;
- Ink_ComboBoxEntry_Action* action = INK_COMBOBOXENTRY_ACTION( data );
- gdk_keymap_translate_keyboard_state( Gdk::Display::get_default()->get_keymap(),
- event->hardware_keycode, (GdkModifierType)event->state,
- 0, &key, nullptr, nullptr, nullptr );
-
- switch ( key ) {
-
- // TODO Add bindings for Tab/LeftTab
- case GDK_KEY_Escape:
- {
- //gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
- ink_comboboxentry_action_defocus( action );
- wasConsumed = TRUE;
- }
- break;
-
- case GDK_KEY_Return:
- case GDK_KEY_KP_Enter:
- {
- ink_comboboxentry_action_defocus( action );
- //wasConsumed = TRUE;
- }
- break;
-
-
- }
-
- return wasConsumed;
-}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :