Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dorota Czaplejewicz
gtk
Commits
247e2aa5
Commit
247e2aa5
authored
Sep 11, 2005
by
Matthias Clasen
Browse files
Forgotten files
parent
1f700be3
Changes
4
Hide whitespace changes
Inline
Side-by-side
gtk/gtkcellrendereraccel.c
0 → 100644
View file @
247e2aa5
/* gtkcellrendererkeys.h
* Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "gtkintl.h"
#include "gtkaccelgroup.h"
#include "gtkmarshalers.h"
#include "gtkcellrendererkeys.h"
#include "gtklabel.h"
#include "gtkeventbox.h"
#include "gtkprivate.h"
#include "gdk/gdkkeysyms.h"
#include "gtkalias.h"
static
void
gtk_cell_renderer_keys_finalize
(
GObject
*
object
);
static
GtkCellEditable
*
gtk_cell_renderer_keys_start_editing
(
GtkCellRenderer
*
cell
,
GdkEvent
*
event
,
GtkWidget
*
widget
,
const
gchar
*
path
,
GdkRectangle
*
background_area
,
GdkRectangle
*
cell_area
,
GtkCellRendererState
flags
);
static
void
gtk_cell_renderer_keys_get_property
(
GObject
*
object
,
guint
param_id
,
GValue
*
value
,
GParamSpec
*
pspec
);
static
void
gtk_cell_renderer_keys_set_property
(
GObject
*
object
,
guint
param_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
);
static
void
gtk_cell_renderer_keys_get_size
(
GtkCellRenderer
*
cell
,
GtkWidget
*
widget
,
GdkRectangle
*
cell_area
,
gint
*
x_offset
,
gint
*
y_offset
,
gint
*
width
,
gint
*
height
);
enum
{
ACCEL_EDITED
,
ACCEL_CLEARED
,
LAST_SIGNAL
};
enum
{
PROP_0
,
PROP_ACCEL_KEY
,
PROP_ACCEL_MODS
,
PROP_KEYCODE
,
PROP_ACCEL_MODE
};
static
guint
signals
[
LAST_SIGNAL
]
=
{
0
};
G_DEFINE_TYPE
(
GtkCellRendererKeys
,
gtk_cell_renderer_keys
,
GTK_TYPE_CELL_RENDERER_TEXT
);
static
void
gtk_cell_renderer_keys_init
(
GtkCellRendererKeys
*
cell_keys
)
{
}
static
void
gtk_cell_renderer_keys_class_init
(
GtkCellRendererKeysClass
*
cell_keys_class
)
{
GObjectClass
*
object_class
;
GtkCellRendererClass
*
cell_renderer_class
;
object_class
=
G_OBJECT_CLASS
(
cell_keys_class
);
cell_renderer_class
=
GTK_CELL_RENDERER_CLASS
(
cell_keys_class
);
GTK_CELL_RENDERER_CLASS
(
cell_keys_class
)
->
start_editing
=
gtk_cell_renderer_keys_start_editing
;
object_class
->
set_property
=
gtk_cell_renderer_keys_set_property
;
object_class
->
get_property
=
gtk_cell_renderer_keys_get_property
;
cell_renderer_class
->
get_size
=
gtk_cell_renderer_keys_get_size
;
object_class
->
finalize
=
gtk_cell_renderer_keys_finalize
;
/**
* GtkCellRendererKeys:accel-key:
*
* The keyval of the accelerator.
*
* Since: 2.10
*/
g_object_class_install_property
(
object_class
,
PROP_ACCEL_KEY
,
g_param_spec_uint
(
"accel-key"
,
P_
(
"Accelerator key"
),
P_
(
"The keyval of the accelerator"
),
0
,
G_MAXINT
,
0
,
GTK_PARAM_READWRITE
));
/**
* GtkCellRendererKeys:accel-mods:
*
* The modifier mask of the accelerator.
*
* Since: 2.10
*/
g_object_class_install_property
(
object_class
,
PROP_ACCEL_MODS
,
g_param_spec_flags
(
"accel-mods"
,
P_
(
"Accelerator modifiers"
),
P_
(
"The modifier mask of the accelerator"
),
GDK_TYPE_MODIFIER_TYPE
,
0
,
GTK_PARAM_READWRITE
));
/**
* GtkCellRendererKeys:keycode:
*
* The hardware keycode of the accelerator. Note that the hardware keycode is
* only relevant if the key does not have a keyval. Normally, the keyboard
* configuration should assign keyvals to all keys.
*
* Since: 2.10
*/
g_object_class_install_property
(
object_class
,
PROP_KEYCODE
,
g_param_spec_uint
(
"keycode"
,
P_
(
"Accelerator keycode"
),
P_
(
"The hardware keycode of the accelerator"
),
0
,
G_MAXINT
,
0
,
GTK_PARAM_READWRITE
));
/**
* GtkCellRendererKeys:accel-mode:
*
* Determines if the edited accelerators are GTK+ accelerators. If
* they are, consumed modifiers are suppressed, only accelerators
* accepted by GTK+ are allowed, and the accelerators are rendered
* in the same way as they are in menus.
*
* Since: 2.10
*/
g_object_class_install_property
(
object_class
,
PROP_ACCEL_MODE
,
g_param_spec_enum
(
"accel-mode"
,
P_
(
"Accelerator Mode"
),
P_
(
"The type of accelerators"
),
GTK_TYPE_CELL_RENDERER_KEYS_MODE
,
GTK_CELL_RENDERER_KEYS_MODE_GTK
,
GTK_PARAM_READWRITE
));
/**
* GtkCellRendererKeys::accel-edited:
* @keys: the object reveiving the signal
* @path_string: the path identifying the row of the edited cell
* @accel_key: the new accelerator keyval
* @accel_mods: the new acclerator modifier mask
* @hardware_keycode: the keycode of the new accelerator
*
* Gets emitted when the user has selected a new accelerator.
*
* Since: 2.10
*/
signals
[
ACCEL_EDITED
]
=
g_signal_new
(
I_
(
"accel-edited"
),
GTK_TYPE_CELL_RENDERER_KEYS
,
G_SIGNAL_RUN_LAST
,
G_STRUCT_OFFSET
(
GtkCellRendererKeysClass
,
accel_edited
),
NULL
,
NULL
,
_gtk_marshal_VOID__STRING_UINT_FLAGS_UINT
,
G_TYPE_NONE
,
4
,
G_TYPE_STRING
,
G_TYPE_UINT
,
GDK_TYPE_MODIFIER_TYPE
,
G_TYPE_UINT
);
/**
* GtkCellRendererKeys::accel-cleared:
* @keys: the object reveiving the signal
* @path_string: the path identifying the row of the edited cell
*
* Gets emitted when the user has removed the accelerator.
*
* Since: 2.10
*/
signals
[
ACCEL_CLEARED
]
=
g_signal_new
(
I_
(
"accel-cleared"
),
GTK_TYPE_CELL_RENDERER_KEYS
,
G_SIGNAL_RUN_LAST
,
G_STRUCT_OFFSET
(
GtkCellRendererKeysClass
,
accel_cleared
),
NULL
,
NULL
,
g_cclosure_marshal_VOID__STRING
,
G_TYPE_NONE
,
1
,
G_TYPE_STRING
);
}
/**
* gtk_cell_renderer_keys_new:
*
* Creates a new #GtkCellRendererKeys.
*
* Returns: the new cell renderer
*
* Since: 2.10
*/
GtkCellRenderer
*
gtk_cell_renderer_keys_new
(
void
)
{
return
GTK_CELL_RENDERER
(
g_object_new
(
GTK_TYPE_CELL_RENDERER_KEYS
,
NULL
));
}
static
void
gtk_cell_renderer_keys_finalize
(
GObject
*
object
)
{
(
*
G_OBJECT_CLASS
(
gtk_cell_renderer_keys_parent_class
)
->
finalize
)
(
object
);
}
static
gchar
*
convert_keysym_state_to_string
(
GtkCellRendererKeys
*
keys
,
guint
keysym
,
GdkModifierType
mask
,
guint
keycode
)
{
if
(
keysym
==
0
&&
keycode
==
0
)
/* This label is displayed in a treeview cell displaying
* a disabled accelerator key combination. Only include
* the text after the | in the translation.
*/
return
g_strdup
(
Q_
(
"Accelerator|Disabled"
));
else
{
if
(
keys
->
accel_mode
==
GTK_CELL_RENDERER_KEYS_MODE_GTK
)
return
gtk_accelerator_get_label
(
keysym
,
mask
);
else
{
gchar
*
name
;
name
=
gtk_accelerator_name
(
keysym
,
mask
);
if
(
keysym
==
0
)
{
gchar
*
tmp
;
tmp
=
name
;
name
=
g_strdup_printf
(
"%s0x%02x"
,
tmp
,
keycode
);
g_free
(
tmp
);
}
return
name
;
}
}
}
static
void
gtk_cell_renderer_keys_get_property
(
GObject
*
object
,
guint
param_id
,
GValue
*
value
,
GParamSpec
*
pspec
)
{
GtkCellRendererKeys
*
keys
;
g_return_if_fail
(
GTK_IS_CELL_RENDERER_KEYS
(
object
));
keys
=
GTK_CELL_RENDERER_KEYS
(
object
);
switch
(
param_id
)
{
case
PROP_ACCEL_KEY
:
g_value_set_uint
(
value
,
keys
->
accel_key
);
break
;
case
PROP_ACCEL_MODS
:
g_value_set_flags
(
value
,
keys
->
accel_mods
);
break
;
case
PROP_ACCEL_MODE
:
g_value_set_enum
(
value
,
keys
->
accel_mode
);
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
param_id
,
pspec
);
}
}
static
void
gtk_cell_renderer_keys_set_property
(
GObject
*
object
,
guint
param_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
)
{
GtkCellRendererKeys
*
keys
;
gboolean
changed
=
FALSE
;
g_return_if_fail
(
GTK_IS_CELL_RENDERER_KEYS
(
object
));
keys
=
GTK_CELL_RENDERER_KEYS
(
object
);
switch
(
param_id
)
{
case
PROP_ACCEL_KEY
:
{
guint
accel_key
=
g_value_get_uint
(
value
);
if
(
keys
->
accel_key
!=
accel_key
)
{
keys
->
accel_key
=
accel_key
;
changed
=
TRUE
;
}
}
break
;
case
PROP_ACCEL_MODS
:
{
guint
accel_mods
=
g_value_get_flags
(
value
);
if
(
keys
->
accel_mods
!=
accel_mods
)
{
keys
->
accel_mods
=
accel_mods
;
changed
=
TRUE
;
}
}
break
;
case
PROP_KEYCODE
:
{
guint
keycode
=
g_value_get_uint
(
value
);
if
(
keys
->
keycode
!=
keycode
)
{
keys
->
keycode
=
keycode
;
changed
=
TRUE
;
}
}
break
;
case
PROP_ACCEL_MODE
:
keys
->
accel_mode
=
g_value_get_enum
(
value
);
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
param_id
,
pspec
);
}
if
(
changed
)
{
GtkCellRendererText
*
celltext
;
gchar
*
text
;
celltext
=
GTK_CELL_RENDERER_TEXT
(
keys
);
text
=
convert_keysym_state_to_string
(
keys
,
keys
->
accel_key
,
keys
->
accel_mods
,
keys
->
keycode
);
g_object_set
(
keys
,
"text"
,
text
,
NULL
);
g_free
(
text
);
}
}
static
void
gtk_cell_renderer_keys_get_size
(
GtkCellRenderer
*
cell
,
GtkWidget
*
widget
,
GdkRectangle
*
cell_area
,
gint
*
x_offset
,
gint
*
y_offset
,
gint
*
width
,
gint
*
height
)
{
GtkCellRendererKeys
*
keys
=
(
GtkCellRendererKeys
*
)
cell
;
GtkRequisition
requisition
;
if
(
keys
->
sizing_label
==
NULL
)
keys
->
sizing_label
=
gtk_label_new
(
_
(
"New accelerator..."
));
gtk_widget_size_request
(
keys
->
sizing_label
,
&
requisition
);
(
*
GTK_CELL_RENDERER_CLASS
(
gtk_cell_renderer_keys_parent_class
)
->
get_size
)
(
cell
,
widget
,
cell_area
,
x_offset
,
y_offset
,
width
,
height
);
/* FIXME: need to take the cell_area et al. into account */
if
(
width
)
*
width
=
MAX
(
*
width
,
requisition
.
width
);
if
(
height
)
*
height
=
MAX
(
*
height
,
requisition
.
height
);
}
static
gboolean
grab_key_callback
(
GtkWidget
*
widget
,
GdkEventKey
*
event
,
void
*
data
)
{
GdkModifierType
accel_mods
=
0
;
guint
accel_key
;
GtkCellRendererKeys
*
keys
;
char
*
path
;
gboolean
edited
;
gboolean
cleared
;
GdkModifierType
consumed_modifiers
;
GdkDisplay
*
display
;
keys
=
GTK_CELL_RENDERER_KEYS
(
data
);
display
=
gtk_widget_get_display
(
widget
);
if
(
event
->
is_modifier
)
return
TRUE
;
edited
=
FALSE
;
cleared
=
FALSE
;
gdk_keymap_translate_keyboard_state
(
gdk_keymap_get_for_display
(
display
),
event
->
hardware_keycode
,
event
->
state
,
event
->
group
,
NULL
,
NULL
,
NULL
,
&
consumed_modifiers
);
accel_key
=
gdk_keyval_to_lower
(
event
->
keyval
);
if
(
accel_key
==
GDK_ISO_Left_Tab
)
accel_key
=
GDK_Tab
;
accel_mods
=
event
->
state
&
gtk_accelerator_get_default_mod_mask
();
/* Filter consumed modifiers
*/
if
(
keys
->
accel_mode
==
GTK_CELL_RENDERER_KEYS_MODE_GTK
)
accel_mods
&=
~
consumed_modifiers
;
/* Put shift back if it changed the case of the key, not otherwise.
*/
if
(
accel_key
!=
event
->
keyval
)
accel_mods
|=
GDK_SHIFT_MASK
;
if
(
accel_mods
==
0
)
{
switch
(
event
->
keyval
)
{
case
GDK_Escape
:
goto
out
;
/* cancel */
case
GDK_BackSpace
:
/* clear the accelerator on Backspace */
cleared
=
TRUE
;
goto
out
;
default:
break
;
}
}
if
(
keys
->
accel_mode
==
GTK_CELL_RENDERER_KEYS_MODE_GTK
)
{
if
(
!
gtk_accelerator_valid
(
accel_key
,
accel_mods
))
{
gdk_display_beep
(
display
);
return
TRUE
;
}
}
edited
=
TRUE
;
out:
gdk_keyboard_ungrab
(
event
->
time
);
gdk_pointer_ungrab
(
event
->
time
);
path
=
g_strdup
(
g_object_get_data
(
G_OBJECT
(
keys
->
edit_widget
),
"gtk-cell-renderer-text"
));
gtk_cell_editable_editing_done
(
GTK_CELL_EDITABLE
(
keys
->
edit_widget
));
gtk_cell_editable_remove_widget
(
GTK_CELL_EDITABLE
(
keys
->
edit_widget
));
keys
->
edit_widget
=
NULL
;
keys
->
grab_widget
=
NULL
;
if
(
edited
)
g_signal_emit
(
keys
,
signals
[
ACCEL_EDITED
],
0
,
path
,
accel_key
,
accel_mods
,
event
->
hardware_keycode
);
else
if
(
cleared
)
g_signal_emit
(
keys
,
signals
[
ACCEL_CLEARED
],
0
,
path
);
g_free
(
path
);
return
TRUE
;
}
static
void
ungrab_stuff
(
GtkWidget
*
widget
,
gpointer
data
)
{
GtkCellRendererKeys
*
keys
=
GTK_CELL_RENDERER_KEYS
(
data
);
gdk_keyboard_ungrab
(
GDK_CURRENT_TIME
);
gdk_pointer_ungrab
(
GDK_CURRENT_TIME
);
g_signal_handlers_disconnect_by_func
(
G_OBJECT
(
keys
->
grab_widget
),
G_CALLBACK
(
grab_key_callback
),
data
);
}
static
void
_gtk_cell_editable_event_box_start_editing
(
GtkCellEditable
*
cell_editable
,
GdkEvent
*
event
)
{
/* do nothing, because we are pointless */
}
static
void
_gtk_cell_editable_event_box_cell_editable_init
(
GtkCellEditableIface
*
iface
)
{
iface
->
start_editing
=
_gtk_cell_editable_event_box_start_editing
;
}
typedef
GtkEventBox
GtkCellEditableEventBox
;
typedef
GtkEventBoxClass
GtkCellEditableEventBoxClass
;
G_DEFINE_TYPE_WITH_CODE
(
GtkCellEditableEventBox
,
_gtk_cell_editable_event_box
,
GTK_TYPE_EVENT_BOX
,
{
\
G_IMPLEMENT_INTERFACE
(
GTK_TYPE_CELL_EDITABLE
,
_gtk_cell_editable_event_box_cell_editable_init
)
\
});
static
void
_gtk_cell_editable_event_box_class_init
(
GtkCellEditableEventBoxClass
*
class
)
{
}
static
void
_gtk_cell_editable_event_box_init
(
GtkCellEditableEventBox
*
box
)
{
}
static
GtkCellEditable
*
gtk_cell_renderer_keys_start_editing
(
GtkCellRenderer
*
cell
,
GdkEvent
*
event
,
GtkWidget
*
widget
,
const
gchar
*
path
,
GdkRectangle
*
background_area
,
GdkRectangle
*
cell_area
,
GtkCellRendererState
flags
)
{
GtkCellRendererText
*
celltext
;
GtkCellRendererKeys
*
keys
;
GtkWidget
*
label
;
GtkWidget
*
eventbox
;
celltext
=
GTK_CELL_RENDERER_TEXT
(
cell
);
keys
=
GTK_CELL_RENDERER_KEYS
(
cell
);
/* If the cell isn't editable we return NULL. */
if
(
celltext
->
editable
==
FALSE
)
return
NULL
;
g_return_val_if_fail
(
widget
->
window
!=
NULL
,
NULL
);
if
(
gdk_keyboard_grab
(
widget
->
window
,
FALSE
,
gdk_event_get_time
(
event
))
!=
GDK_GRAB_SUCCESS
)
return
NULL
;
if
(
gdk_pointer_grab
(
widget
->
window
,
FALSE
,
GDK_BUTTON_PRESS_MASK
,
NULL
,
NULL
,
gdk_event_get_time
(
event
))
!=
GDK_GRAB_SUCCESS
)
{
gdk_keyboard_ungrab
(
gdk_event_get_time
(
event
));
return
NULL
;
}
keys
->
grab_widget
=
widget
;
g_signal_connect
(
G_OBJECT
(
widget
),
"key_press_event"
,
G_CALLBACK
(
grab_key_callback
),
keys
);
eventbox
=
g_object_new
(
_gtk_cell_editable_event_box_get_type
(),
NULL
);
keys
->
edit_widget
=
eventbox
;
g_object_add_weak_pointer
(
G_OBJECT
(
keys
->
edit_widget
),
(
void
**
)
&
keys
->
edit_widget
);
label
=
gtk_label_new
(
NULL
);
gtk_misc_set_alignment
(
GTK_MISC
(
label
),
0
.
0
,
0
.
5
);
gtk_widget_modify_bg
(
eventbox
,
GTK_STATE_NORMAL
,
&
widget
->
style
->
bg
[
GTK_STATE_SELECTED
]);
gtk_widget_modify_fg
(
label
,
GTK_STATE_NORMAL
,
&
widget
->
style
->
fg
[
GTK_STATE_SELECTED
]);
/* This label is displayed in a treeview cell displaying
* an accelerator when the cell is clicked to change the
* acelerator.
*/
gtk_label_set_text
(
GTK_LABEL
(
label
),
_
(
"New accelerator..."
));
gtk_container_add
(
GTK_CONTAINER
(
eventbox
),
label
);
g_object_set_data_full
(
G_OBJECT
(
keys
->
edit_widget
),
"gtk-cell-renderer-text"
,
g_strdup
(
path
),
g_free
);
gtk_widget_show_all
(
keys
->
edit_widget
);
g_signal_connect
(
G_OBJECT
(
keys
->
edit_widget
),
"unrealize"
,
G_CALLBACK
(
ungrab_stuff
),
keys
);
return
GTK_CELL_EDITABLE
(
keys
->
edit_widget
);
}
#define __GTK_CELL_RENDERER_KEYS_C__
#include "gtkaliasdef.c"
gtk/gtkcellrendereraccel.h
0 → 100644
View file @
247e2aa5
/* gtkcellrendererkeys.h
* Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.