Index: gazpacho/commandmanager.py
===================================================================
--- gazpacho/commandmanager.py	(revision 2393)
+++ gazpacho/commandmanager.py	(working copy)
@@ -18,7 +18,7 @@
 from kiwi.ui.dialogs import warning
 
 from gazpacho.clipboard import clipboard
-from gazpacho.gaction import GAction, GActionGroup
+from gazpacho.gaction import GAction, GToggleAction, GRadioAction, GActionGroup
 from gazpacho.i18n import _
 from gazpacho.sizegroup import safe_to_add_gadgets
 from gazpacho.util import get_parent
@@ -223,11 +223,11 @@
 
         return gadget
 
-    def add_action(self, values, parent, project):
-        gact = GAction(parent, values['name'], values['label'],
-                       values['short_label'], values['is_important'],
-                       values['tooltip'], values['stock_id'],
-                       values['callback'], values['accelerator'])
+    def add_action(self, action_type, values, parent, project):
+        gactions = { gtk.Action: GAction,
+                     gtk.ToggleAction: GToggleAction,
+                     gtk.RadioAction: GRadioAction }
+        gact = gactions[action_type](parent, **values)
         dsc = _('Add action %s') % gact.name
         cmd = self._get_command('add-action', parent, gact, True, dsc)
         cmd.execute()
Index: gazpacho/filewriter.py
===================================================================
--- gazpacho/filewriter.py	(revision 2393)
+++ gazpacho/filewriter.py	(working copy)
@@ -21,6 +21,7 @@
 import gobject
 import gtk
 
+from gazpacho.gaction import GAction, GToggleAction, GRadioAction
 from gazpacho.choice import enum_to_string, flags_to_string
 from gazpacho.placeholder import Placeholder
 from gazpacho.properties import prop_registry
@@ -234,11 +235,16 @@
         action_names = action_group.get_action_names()
         action_names.sort()
 
+        action_writers = { GAction: self._write_action,
+                           GToggleAction: self._write_toggle_action,
+                           GRadioAction: self._write_radio_action }
+
         for action_name in action_names:
             child_node = self._doc.createElement('child')
             node.appendChild(child_node)
             action = action_group.get_action(action_name)
-            child_node.appendChild(self._write_action(action))
+            action_writer = action_writers[type(action)]
+            child_node.appendChild(action_writer(action))
 
         return node
 
@@ -295,6 +301,26 @@
                 action_node.appendChild(node)
         return action_node
 
+    def _write_toggle_action(self, action):
+        action_node = self._write_action(action)
+        action_node.setAttribute('class', 'GtkToggleAction')
+        if action.active:
+            node = self._write_property('active', 'True')
+            action_node.appendChild(node)
+        if action.draw_as_radio:
+            node = self._write_property('draw-as-radio', 'True')
+            action_node.appendChild(node)
+        return action_node
+
+    def _write_radio_action(self, action):
+        action_node = self._write_toggle_action(action)
+        action_node.setAttribute('class', 'GtkRadioAction')
+        if action.value:
+            node = self._write_property('value', str(action.value))
+            action_node.appendChild(node)
+        # XXX write the group
+        return action_node
+
     def _write_model(self, root, model):
         # <widget>
         #   <columns>
Index: gazpacho/command.py
===================================================================
--- gazpacho/command.py	(revision 2393)
+++ gazpacho/command.py	(working copy)
@@ -18,6 +18,7 @@
 import gobject
 from kiwi.component import get_utility
 
+from gazpacho import gaction
 from gazpacho import util
 from gazpacho.app.bars import bar_manager
 from gazpacho.commandmanager import command_manager
@@ -608,6 +609,16 @@
         self.gact.tooltip = self.new_values['tooltip']
         self.gact.accelerator = self.new_values['accelerator']
         self.gact.callback = self.new_values['callback']
+        if isinstance(self.gact, gaction.GToggleAction):
+            old_values['active'] = self.gact.active
+            self.gact.active = self.new_values['active']
+            old_values['draw_as_radio'] = self.gact.draw_as_radio
+            self.gact.draw_as_radio = self.new_values['draw_as_radio']
+            if isinstance(self.gact, gaction.GRadioAction):
+                old_values['value'] = self.gact.value
+                self.gact.value = self.new_values['value']
+                old_values['group'] = self.gact.group
+                self.gact.group = self.new_values['group']
         self.gact.parent.update_action(self.gact, old_values['name'])
         self.new_values = old_values
         self.project.change_action_name(self.gact)
Index: gazpacho/actioneditor.py
===================================================================
--- gazpacho/actioneditor.py	(revision 2393)
+++ gazpacho/actioneditor.py	(working copy)
@@ -22,7 +22,7 @@
 
 from gazpacho.app.bars import bar_manager
 from gazpacho.commandmanager import command_manager
-from gazpacho.gaction import GAction, GActionGroup
+from gazpacho.gaction import GAction, GToggleAction, GRadioAction, GActionGroup
 from gazpacho.i18n import _
 from gazpacho.interfaces import IGazpachoApp
 from gazpacho.stockicons import StockIconList
@@ -104,8 +104,10 @@
         dialog = GActionDialog(
             get_utility(IGazpachoApp).get_window(), parent, None)
         if dialog.run() == gtk.RESPONSE_OK:
+            action_type = dialog.action_type
             values = dialog.get_values()
-            command_manager.add_action(values, parent, self.project)
+            command_manager.add_action(action_type, values, parent,
+                                       self.project)
         dialog.destroy()
 
     def add_action_group(self):
@@ -306,6 +308,7 @@
 
         self._create_widgets()
 
+        self.action_group = action_group
         self.action = edit_action
 
         self.set_default_response(gtk.RESPONSE_OK)
@@ -319,11 +322,31 @@
                           self._on_mnemonic_activate, keyval)
 
         self.vbox.show_all()
+        self._update_ui_visibility()
 
     def _create_widgets(self):
 
         size_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
 
+        # type chooser/label
+        hbox = gtk.HBox(spacing=6)
+        label = self._create_label(_('_Type'), size_group, hbox)
+
+        type_model = gtk.ListStore(str, object)
+        type_model.append((_('Action'), gtk.Action))
+        type_model.append((_('Toggle Action'), gtk.ToggleAction))
+        type_model.append((_('Radio Action'), gtk.RadioAction))
+
+        self.action_type_combo = gtk.ComboBox(type_model)
+        cell = gtk.CellRendererText()
+        self.action_type_combo.pack_start(cell, True)
+        self.action_type_combo.add_attribute(cell, 'text', 0)
+        self.action_type_combo.connect('changed', self._on_type_combo_changed)
+
+        label.set_mnemonic_widget(self.action_type_combo)
+        hbox.pack_start(self.action_type_combo)
+        self.vbox.pack_start(hbox)
+
         # id
         hbox = gtk.HBox(spacing=6)
         label = self._create_label('_Id', size_group, hbox)
@@ -395,7 +418,7 @@
 
         # tooltip
         hbox = gtk.HBox(spacing=6)
-        label = self._create_label(_('_Tooltip'), size_group, hbox)
+        label = self._create_label(_('T_ooltip'), size_group, hbox)
         self.tooltip = gtk.Entry()
         self.tooltip.set_activates_default(True)
         label.set_mnemonic_widget(self.tooltip)
@@ -411,6 +434,51 @@
         hbox.pack_start(self.callback)
         self.vbox.pack_start(hbox)
 
+        self.toggle_widgets = []
+
+        # active (toggle, radio)
+        hbox = gtk.HBox(spacing=6)
+        label = self._create_label(_('_Active'), size_group, hbox)
+        self.active = gtk.CheckButton()
+        label.set_mnemonic_widget(self.active)
+        hbox.pack_start(self.active, False, False)
+        self.vbox.pack_start(hbox)
+        self.toggle_widgets.append(hbox)
+
+        # draw as radio (toggle, radio)
+        hbox = gtk.HBox(spacing=6)
+        label = self._create_label(_('Draw As _Radio'), size_group, hbox)
+        self.draw_as_radio = gtk.CheckButton()
+        label.set_mnemonic_widget(self.draw_as_radio)
+        hbox.pack_start(self.draw_as_radio, False, False)
+        self.vbox.pack_start(hbox)
+        self.toggle_widgets.append(hbox)
+
+        self.radio_widgets = []
+
+        # value
+        hbox = gtk.HBox(spacing=6)
+        label = self._create_label(_('_Value'), size_group, hbox)
+        adjustment = gtk.Adjustment(0, 0, 9999, 1, 10)
+        self.radio_value = gtk.SpinButton(adjustment)
+        label.set_mnemonic_widget(self.radio_value)
+        hbox.pack_start(self.radio_value)
+        self.vbox.pack_start(hbox)
+        self.radio_widgets.append(hbox)
+
+        # group
+        hbox = gtk.HBox(spacing=6)
+        label = self._create_label(_('_Group With'), size_group, hbox)
+        radio_group_model = gtk.ListStore(str, object)
+        self.radio_group = gtk.ComboBox(radio_group_model)
+        cell = gtk.CellRendererText()
+        self.radio_group.pack_start(cell, True)
+        self.radio_group.add_attribute(cell, 'text', 0)
+        label.set_mnemonic_widget(self.radio_group)
+        hbox.pack_start(self.radio_group)
+        self.vbox.pack_start(hbox)
+        self.radio_widgets.append(hbox)
+
     def _create_label(self, text, size_group, hbox):
         label = gtk.Label()
         label.set_markup_with_mnemonic(text+':')
@@ -423,6 +491,21 @@
         hbox.pack_start(label, False, False)
         return label
 
+    def _update_ui_visibility(self):
+        if self.action_type == gtk.ToggleAction:
+            show = self.toggle_widgets
+            hide = self.radio_widgets
+        elif self.action_type == gtk.RadioAction:
+            show = self.toggle_widgets + self.radio_widgets
+            hide = ()
+        else:
+            show = ()
+            hide = self.toggle_widgets + self.radio_widgets
+        for w in show:
+            w.show();
+        for w in hide:
+            w.hide();
+
     def on_accelerator_focus_in(self, widget, event):
         """
         Callback for when the accelerator entry gets focus.
@@ -500,6 +583,13 @@
         menu.popup(None, None, None, event.button, event.time)
         return True
 
+    def _on_type_combo_changed(self, widget):
+        """
+        Callback for when the action type combobox changes
+        """
+        self.action_type = widget.get_model()[widget.get_active()][1]
+        self._update_ui_visibility()
+
     def _on_id_entry_changed(self, entry):
         """
         Callback used for disabling the ok button if the name of the
@@ -525,6 +615,8 @@
         self._update_button()
 
     def _clear_widgets(self):
+        self.action_type_combo.set_active(0)
+        self.action_type_combo.set_sensitive(True)
         self.id.set_text('')
         self.label.set_text('')
         self.short_label.set_text('')
@@ -534,8 +626,16 @@
         self.accelerator.set_text('')
         self.tooltip.set_text('')
         self.callback.set_text('')
+        self.active.set_active(False)
+        self.draw_as_radio.set_active(False)
+        self.radio_value.set_value(0)
+        self.radio_group.set_active(-1)
+        self.radio_group.get_model().clear()
 
     def _load_widgets(self):
+        self.action_type_combo.set_active(
+            [GAction, GToggleAction, GRadioAction].index(type(self._action)))
+        self.action_type_combo.set_sensitive(False)
         self.id.set_text(self._action.name)
         self.label.set_text(self._action.label)
         self.short_label.set_text(self._action.short_label or '')
@@ -550,6 +650,21 @@
         self.accelerator.set_text(self._action.accelerator or '')
         self.tooltip.set_text(self._action.tooltip or '')
         self.callback.set_text(self._action.callback or '')
+        if self.action_type in (gtk.ToggleAction, gtk.RadioAction):
+            self.active.set_active(self._action.active)
+            self.draw_as_radio.set_active(self._action.draw_as_radio)
+            if self.action_type == gtk.RadioAction:
+                self.radio_value.set_value(self._action.value)
+                model = self.radio_group.get_model()
+                model.clear()
+                for i, action in enumerate(self.action_group.get_actions()):
+                    if (isinstance(action, GRadioAction) and
+                        action != self._action):
+                        model.append((action.name, action))
+                        if action.group == self._action.group:
+                            self.radio_group.set_active(i);
+                else:
+                    self.radio_group.set_active(-1);
 
     def _fill_action(self):
         self._action.name = self.id.get_text()
@@ -563,6 +678,15 @@
         self._action.accelerator = self.accelerator.get_text()
         self._action.tooltip = self.tooltip.get_text()
         self._action.callback = self.callback.get_text()
+        if self.action_type in (gtk.ToggleAction, gtk.RadioAction):
+            self._action.active = self.active.get_active()
+            self._action.draw_as_radio = self.draw_as_radio.get_active()
+            if self.action_type == gtk.RadioAction:
+                self._action.value = self.radio_value.get_value_as_int()
+                active = self.radio_group.get_active()
+                self._action.group = (active != -1
+                                      and self.radio.get_model()[active][1]
+                                      or None)
 
     def get_action(self):
         self._fill_action()
@@ -570,9 +694,11 @@
 
     def set_action(self, gaction):
         if gaction is None:
+            self.action_type = GAction
             self._clear_widgets()
             self._action = GAction(None)
         else:
+            self.action_type = type(gaction)
             self._action = gaction
             self._load_widgets()
 
@@ -591,6 +717,16 @@
             stock_id = self.stock.get_stock_id()
         values['stock_id'] = stock_id
 
+        if self.action_type in (gtk.ToggleAction, gtk.RadioAction):
+            values['active'] = self.active.get_active()
+            values['draw_as_radio'] = self.draw_as_radio.get_active()
+            if self.action_type == gtk.RadioAction:
+                values['value'] = self.radio_value.get_value_as_int()
+                active = self.radio_group.get_active()
+                values['group'] = (active != -1
+                                   and self.radio_group.get_model()[active][1]
+                                   or None)
+
         return values
 
 gobject.type_register(GActionDialog)
Index: gazpacho/gaction.py
===================================================================
--- gazpacho/gaction.py	(revision 2393)
+++ gazpacho/gaction.py	(working copy)
@@ -25,7 +25,7 @@
     """
     def __init__(self, parent, name='', label='',
                  short_label='', is_important=False,
-                 tooltip='', stock_id=None, callback='', accel=''):
+                 tooltip='', stock_id=None, callback='', accelerator=''):
         # parent GActionGroup
         self.parent = parent
 
@@ -39,7 +39,7 @@
         self.tooltip = tooltip
         self.stock_id = stock_id
         self.callback = callback
-        self.accelerator = accel
+        self.accelerator = accelerator
 
     def new(cls, gtk_action, parent):
         """Create a new GAction from a GtkAction and a GtkActionGroup"""
@@ -78,6 +78,72 @@
     def get_name(self):
         return self.name
 
+    def new_gtk_action(self):
+        gtk_action = gtk.Action(self.name, self.label,
+                                self.tooltip, self.stock_id)
+        # don't set a zero-length short label
+        if self.short_label:
+            gtk_action.set_property('short-label', self.short_label)
+        gtk_action.set_property('is-important', self.is_important)
+        return gtk_action
+
+class GToggleAction(GAction):
+    """A GAction for GtkToggleActions.
+    """
+    def __init__(self, parent, name='', label='',
+                 short_label='', is_important=False,
+                 tooltip='', stock_id=None, callback='', accelerator='',
+                 active=False, draw_as_radio=False):
+        GAction.__init__(self, parent, name, label, short_label,
+                         is_important, tooltip, stock_id, callback, accelerator)
+        self.active = active
+        self.draw_as_radio = draw_as_radio
+
+    def new(cls, gtk_action, parent):
+        gaction = super(GToggleAction, cls).new(gtk_action, parent)
+        gaction.active =  gtk_action.get_active()
+        gaction.draw_as_radio = gtk_action.get_property('draw-as-radio')
+        return gaction
+    new = classmethod(new)
+
+    def new_gtk_action(self):
+        gtk_action = gtk.ToggleAction(self.name, self.label,
+                                      self.tooltip, self.stock_id)
+        # don't set a zero-length short label
+        if self.short_label:
+            gtk_action.set_property('short-label', self.short_label)
+        gtk_action.set_property('is-important', self.is_important)
+        return gtk_action
+
+class GRadioAction(GToggleAction):
+    """A GAction for GtkRadioActions.
+    """
+    def __init__(self, parent, name='', label='',
+                 short_label='', is_important=False,
+                 tooltip='', stock_id=None, callback='', accelerator='',
+                 active=False, draw_as_radio=False, value=0, group=None):
+        GToggleAction.__init__(self, parent, name, label, short_label,
+                               is_important, tooltip, stock_id, callback,
+                               accelerator, active, draw_as_radio)
+        self.group = group
+        self.value = value
+
+    def new(cls, gtk_action, parent):
+        gaction = super(GRadioAction, cls).new(gtk_action, parent)
+        gaction.value = gtk_action.get_property('value')
+        gaction.group = gtk_action.get_group()
+        return gaction
+    new = classmethod(new)
+
+    def new_gtk_action(self):
+        gtk_action = gtk.RadioAction(self.name, self.label, self.tooltip,
+                                     self.stock_id, self.value)
+        # don't set a zero-length short label
+        if self.short_label:
+            gtk_action.set_property('short-label', self.short_label)
+        gtk_action.set_property('is-important', self.is_important)
+        return gtk_action
+
 class GActionGroup(gobject.GObject):
     """A GActionGroup is just a list of GActions with a name.
     Associated with each GActionGroup there is a GtkActionGroup with
@@ -163,12 +229,7 @@
             # are not exactly the same as the old one
 
     def _add_gtk_action(self, action):
-        gtk_action = gtk.Action(action.name, action.label,
-                                action.tooltip, action.stock_id)
-        # don't set a zero-length short label
-        if action.short_label:
-            gtk_action.set_property('short-label', action.short_label)
-        gtk_action.set_property('is-important', action.is_important)
+        gtk_action = action.new_gtk_action()
         gtk_action_group = self.get_data('gtk_action_group')
         gtk_action_group.add_action_with_accel(gtk_action, action.accelerator)
 
Index: gazpacho/uim.py
===================================================================
--- gazpacho/uim.py	(revision 2393)
+++ gazpacho/uim.py	(working copy)
@@ -20,7 +20,7 @@
 
 import gtk
 
-from gazpacho.gaction import GAction, GActionGroup
+from gazpacho.gaction import GAction, GToggleAction, GRadioAction, GActionGroup
 
 default_actions = [
     # name, label, short_label, is_important,
@@ -242,6 +242,9 @@
                 gaction_callbacks[widget] = handler
 
         # read the action groups
+        action_types = { gtk.Action: GAction,
+                         gtk.ToggleAction: GToggleAction,
+                         gtk.RadioAction: GRadioAction }
         for ag in uimanager.get_action_groups():
             # only add the action group if we don't have it
             gag = self.get_action_group(ag.get_name())
@@ -249,7 +252,7 @@
                 gag = GActionGroup.new(ag)
                 self.add_action_group(gag)
             for action in ag.list_actions():
-                ga = GAction.new(action, gag)
+                ga = action_types[type(action)].new(action, gag)
                 # only add the action if the action group does not have it
                 if not gag.get_action(ga.name):
                     ga.callback = gaction_callbacks.get(action, '')
Index: gazpacho/loader/custom.py
===================================================================
--- gazpacho/loader/custom.py	(revision 2393)
+++ gazpacho/loader/custom.py	(working copy)
@@ -480,6 +480,16 @@
         if value:
             self._build.add_signal(action, 'activate', value)
 
+class ToggleActionAdapter(ActionAdapter):
+    object_type = gtk.ToggleAction
+
+    def prop_set_active(self, action, value):
+        # there is no 'active' property on gtk.ToggleAction objects
+        action.set_active(str2bool(value))
+
+class RadioActionAdapter(ToggleActionAdapter):
+    object_type = gtk.RadioAction
+
 class PixmapAdapter(WidgetAdapter):
     object_type = gtk.Pixmap
     def prop_set_build_insensitive(self, pixmap, value):
