ink-comboboxentry-action.cpp revision 5018d95ebe4fcf268f7751ecea14d477735924d9
/*
* 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, 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 <string.h>
#include <gdk/gdkkeysyms.h>
#include "ink-comboboxentry-action.h"
// Must handle both tool and menu items!
// Internal
// Callbacks
static gboolean match_selected_cb( GtkEntryCompletion* widget, GtkTreeModel* model, GtkTreeIter* iter, gpointer data );
enum {
PROP_MODEL = 1,
};
enum {
CHANGED = 0,
};
{
// Free any allocated resources.
}
static void ink_comboboxentry_action_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch(property_id) {
case PROP_MODEL:
break;
case PROP_COMBOBOX:
break;
case PROP_ENTRY:
break;
case PROP_ENTRY_WIDTH:
break;
case PROP_EXTRA_WIDTH:
break;
case PROP_CELL_DATA_FUNC:
break;
case PROP_POPUP:
break;
case PROP_FOCUS_WIDGET:
break;
default:
}
}
static void ink_comboboxentry_action_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
switch(property_id) {
case PROP_MODEL:
break;
case PROP_COMBOBOX:
break;
case PROP_ENTRY:
break;
case PROP_ENTRY_WIDTH:
break;
case PROP_EXTRA_WIDTH:
break;
case PROP_CELL_DATA_FUNC:
break;
case PROP_POPUP:
break;
case PROP_FOCUS_WIDGET:
break;
default:
}
}
static void
{
/* Override any proxy properties. */
// if (GTK_IS_MENU_ITEM (proxy)) {
// }
}
{
g_param_spec_object ("model",
"Tree Model",
"Tree Model",
g_param_spec_object ("combobox",
"GtkComboBoxEntry",
"GtkComboBoxEntry",
g_param_spec_object ("entry",
"GtkEntry",
"GtkEntry",
g_param_spec_int ("entry_width",
"EntryBox width",
"EntryBox width (characters)",
-1.0, 100, -1.0,
g_param_spec_int ("extra_width",
"Extra width",
"Extra width (px)",
-1.0, 500, -1.0,
g_param_spec_pointer ("cell_data_func",
"Cell Data Func",
"Cell Deta Function",
g_param_spec_boolean ("popup",
"Entry Popup",
"Entry Popup",
false,
g_param_spec_pointer( "focus-widget",
"Focus Widget",
"The widget to return focus to",
// We need to know when GtkComboBoxEvent or Menu ready for reading
G_TYPE_NONE, 0);
// Probably not needed... originally to keep track of key-presses.
G_TYPE_NONE, 0);
}
{
}
{
static GType ink_comboboxentry_action_type = 0;
if (!ink_comboboxentry_action_type) {
static const GTypeInfo ink_comboboxentry_action_info = {
sizeof(Ink_ComboBoxEntry_ActionClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(Ink_ComboBoxEntry_Action),
0, /* n_preallocs */
NULL /* value_table */
};
"Ink_ComboBoxEntry_Action",
(GTypeFlags)0 );
}
return ink_comboboxentry_action_type;
}
void *cell_data_func,
{
"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,
"focus-widget", focusWidget,
NULL);
}
// Create a widget for a toolbar.
{
g_free( action_name );
// Backward-compatibility: GtkComboBoxEntry is deprecated in GTK+ >= 2.24
// gtk_combo_box_set_entry_text_column is unavailable in earlier versions
#else
#endif
// Name it so we can muck with it using an RC file
g_free( combobox_name );
{
}
// Optionally add formatting...
}
// Optionally widen the combobox width... which widens the drop-down list in list mode.
if( ink_comboboxentry_action->extra_width > 0 ) {
#if GTK_CHECK_VERSION(3,0,0)
#else
#endif
}
// Get reference to GtkEntry and fiddle a bit with it.
// Name it so we can muck with it using an RC file
g_free( entry_name );
// Change width
if( ink_comboboxentry_action->entry_width > 0 ) {
}
// Add pop-up entry completion if required
if( ink_comboboxentry_action->popup ) {
}
// 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.
}
} else {
}
return item;
}
// Create a drop-down menu.
{
g_warning( "ink_comboboxentry_action: create_menu_item not implemented" );
// One can easily modify ege-select-one-action routine to implement this.
return item;
}
}
}
return text;
}
gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* ink_comboboxentry_action, const gchar* text ) {
// Get active row or -1 if none
ink_comboboxentry_action->active = get_active_row_from_text( ink_comboboxentry_action, ink_comboboxentry_action->text );
// Set active row, check that combobox has been created.
if( ink_comboboxentry_action->combobox ) {
gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox ), ink_comboboxentry_action->active );
}
// Fiddle with entry
if( ink_comboboxentry_action->entry ) {
// Explicitly set text in GtkEntry box (won't be set if text not in list).
// Show or hide warning
{
if (isStock) {
} else {
}
}
// Can't add tooltip until icon set
} else {
NULL );
NULL );
}
}
// Return if active text in list
return found;
}
void ink_comboboxentry_action_set_entry_width( Ink_ComboBoxEntry_Action* action, gint entry_width ) {
// Widget may not have been created....
}
}
void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, gint extra_width ) {
// Widget may not have been created....
#if GTK_CHECK_VERSION(3,0,0)
#else
#endif
}
}
// Widget may not have been created....
// Check we don't already have a GtkEntryCompletion
if( action->entry_completion ) return;
g_signal_connect (G_OBJECT (action->entry_completion), "match-selected", G_CALLBACK (match_selected_cb), action );
}
}
if( action->entry_completion ) {
action->entry_completion = 0;
}
}
void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip ) {
// Widget may not have been created....
}
}
}
void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning ) {
// Widget may not have been created....
}
}
void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name ) {
// Widget may not have been created....
}
}
// Internal ---------------------------------------------------
// Return row of active text or -1 if not found.
// Check if text in list
while ( valid ) {
// Get text from list entry
// Check for match
found = true;
break;
}
++row;
}
return row;
}
// Checks if all comma separated text fragments are in the list.
// This is useful for checking if all fonts in a font-family fallback
// list are available on the system.
// The return value is set to the number of missing text fragments.
// This routine could also create a Pango Markup string to show which
// fragments are invalid.
// It is envisioned that one can construct a Pango Markup String here
// so that individual text fragments can be flagged as not being in the
// list.
// Parse fallback_list using a comma as deliminator
gint i = 0;
// Remove any surrounding white space.
g_strstrip( tokens[i] );
ret_val += 1;
}
++i;
}
g_strfreev( tokens );
// Pango Markup notes:
// GString* Pango_Markup = g_string_new("");
// if not present:
// g_string_sprintfa( Pango_Markup, "<span strikethrough=\"true\" strikethrough_color=\"#880000\">%s</span>", tokens[i] );
// PangoLayout * pl = gtk_entry_get_layout( entry );
// pango_layout_set_markup( pl, Pango_Markup->str, -1 );
// g_string_free( Pango_Markup, TRUE );
return ret_val;
}
// Callbacks ---------------------------------------------------
// 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
// Check if item selected:
if( newActive >= 0 ) {
// Now let the world know
}
}
}
// Get text from entry box.. check if it matches a menu entry.
// Get action
// Get text
// Get row
// Set active row
gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox), ink_comboboxentry_action->active );
// Now let the world know
}
static gboolean match_selected_cb( GtkEntryCompletion* /*widget*/, GtkTreeModel* model, GtkTreeIter* iter, gpointer data )
{
// Get action
if( entry) {
// Set text in GtkEntry
// Set text in GtkAction
// Get row
// Set active row
gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox), ink_comboboxentry_action->active );
// Now let the world know
return true;
}
return false;
}
{
if ( action->focusWidget ) {
}
}
{
0, &key, 0, 0, 0 );
switch ( key ) {
case GDK_KEY_Escape:
{
//gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
wasConsumed = TRUE;
}
break;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
{
//wasConsumed = TRUE;
}
break;
}
return wasConsumed;
}