# HG changeset patch
# User K. Arvanitis <kosta@alumni.uvic.ca>
# Date 1422941391 28800
# Parent  5a17f1c24b38875fe8ef83b6a3fe6b61f11c07af
[PATCH] Radio settings flattened view

Due to the nested nature of the settings editor tree view, labels in the 
tree generally become obscured because the pane is too small.  

This change addresses the issue by a) adding a horizontal paned window 
which allows the tree view to be manually resized while b) flattening 
the radio featrure radio settings group to return a single list of 
all top level radio settings groups.


Bug #2285

diff -r 5a17f1c24b38 chirp/alinco.py
--- a/chirp/alinco.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/alinco.py	Mon Feb 02 22:12:53 2015 -0800
@@ -14,8 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from chirp import chirp_common, bitwise, memmap, errors, directory, util
-from chirp.settings import RadioSettingGroup, RadioSetting
-from chirp.settings import RadioSettingValueBoolean
+from chirp.settings import *
 
 import time
 
diff -r 5a17f1c24b38 chirp/anytone.py
--- a/chirp/anytone.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/anytone.py	Mon Feb 02 22:12:53 2015 -0800
@@ -23,8 +23,7 @@
 from chirp import errors
 from chirp import memmap
 from chirp import util
-from chirp.settings import RadioSettingGroup, RadioSetting, \
-    RadioSettingValueList, RadioSettingValueString, RadioSettingValueBoolean
+from chirp.settings import *
 
 _mem_format = """
 #seekto 0x0100;
@@ -475,19 +474,20 @@
 
     def get_settings(self):
         _settings = self._memobj.settings
-        settings = RadioSettingGroup('all', 'All Settings')
+        basic = RadioSettingGroup("basic", "Basic")
+        settings = RadioSettings(basic)
 
         display = ["Frequency", "Channel", "Name"]
         rs = RadioSetting("display", "Display",
                           RadioSettingValueList(display,
                                                 display[_settings.display]))
-        settings.append(rs)
+        basic.append(rs)
 
         apo = ["Off"] + ['%.1f hour(s)' % (0.5 * x) for x in range(1, 25)]
         rs = RadioSetting("apo", "Automatic Power Off",
                           RadioSettingValueList(apo,
                                                 apo[_settings.apo]))
-        settings.append(rs)
+        basic.append(rs)
 
         def filter(s):
             s_ = ""
@@ -499,23 +499,26 @@
         rs = RadioSetting("welcome", "Welcome Message",
                           RadioSettingValueString(0, 8,
                                                   filter(_settings.welcome)))
-        settings.append(rs)
+        basic.append(rs)
 
         rs = RadioSetting("beep", "Beep Enabled",
                           RadioSettingValueBoolean(_settings.beep))
-        settings.append(rs)
+        basic.append(rs)
 
         mute = ["Off", "TX", "RX", "TX/RX"]
         rs = RadioSetting("mute", "Sub Band Mute",
                           RadioSettingValueList(mute,
                                                 mute[_settings.mute]))
-        settings.append(rs)
+        basic.append(rs)
 
         return settings
 
     def set_settings(self, settings):
         _settings = self._memobj.settings
         for element in settings:
+            if not isinstance(element, RadioSetting):
+                self.set_settings(element)
+                continue
             name = element.get_name()
             setattr(_settings, name, element.value)
 
diff -r 5a17f1c24b38 chirp/ap510.py
--- a/chirp/ap510.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ap510.py	Mon Feb 02 22:12:53 2015 -0800
@@ -15,10 +15,7 @@
 
 import struct
 from chirp import chirp_common, directory, errors, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, RadioSettingValue, InvalidValueError
+from chirp.settings import *
 
 
 def encode_base100(v):
@@ -313,7 +310,7 @@
         aprs = RadioSettingGroup("aprs", "APRS", china, smartbeacon)
         digipeat = RadioSettingGroup("digipeat", "Digipeat")
         system = RadioSettingGroup("system", "System")
-        settings = RadioSettingGroup("all", "Settings", aprs, digipeat, system)
+        settings = RadioSettings(aprs, digipeat, system)
 
         # The RadioSetting syntax is really verbose, iterate it.
         fields = [
diff -r 5a17f1c24b38 chirp/baofeng_uv3r.py
--- a/chirp/baofeng_uv3r.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/baofeng_uv3r.py	Mon Feb 02 22:12:53 2015 -0800
@@ -19,10 +19,7 @@
 import os
 from chirp import util, chirp_common, bitwise, errors, directory
 from chirp.wouxun_common import do_download, do_upload
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-                RadioSettingValueBoolean, RadioSettingValueList, \
-                RadioSettingValueInteger, RadioSettingValueString, \
-                RadioSettingValueFloat
+from chirp.settings import *
 
 if os.getenv("CHIRP_DEBUG"):
     DEBUG = True
@@ -357,7 +354,7 @@
         _settings = self._memobj.settings
         _vfo = self._memobj.vfo
         basic = RadioSettingGroup("basic", "Basic Settings")
-        group = RadioSettingGroup("top", "All Settings", basic)
+        group = RadioSettings(basic)
 
         rs = RadioSetting("squelch", "Squelch Level",
                           RadioSettingValueInteger(0, 9, _settings.squelch))
diff -r 5a17f1c24b38 chirp/bjuv55.py
--- a/chirp/bjuv55.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/bjuv55.py	Mon Feb 02 22:12:53 2015 -0800
@@ -21,10 +21,7 @@
 
 from chirp import chirp_common, errors, util, directory, memmap
 from chirp import bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, InvalidValueError
+from chirp.settings import *
 from textwrap import dedent
 from chirp import uv5r
 
@@ -270,7 +267,7 @@
         _settings = self._memobj.settings
         basic = RadioSettingGroup("basic", "Basic Settings")
         advanced = RadioSettingGroup("advanced", "Advanced Settings")
-        group = RadioSettingGroup("top", "All Settings", basic, advanced)
+        group = RadioSettings(basic, advanced)
 
         rs = RadioSetting("squelch", "Carrier Squelch Level",
                           RadioSettingValueInteger(0, 9, _settings.squelch))
diff -r 5a17f1c24b38 chirp/chirp_common.py
--- a/chirp/chirp_common.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/chirp_common.py	Mon Feb 02 22:12:53 2015 -0800
@@ -248,7 +248,7 @@
 
     immutable = []
 
-    # A RadioSettingsGroup of additional settings supported by the radio,
+    # A RadioSettingGroup of additional settings supported by the radio,
     # or an empty list if none
     extra = []
 
@@ -1027,7 +1027,7 @@
         return rf.validate_memory(mem)
 
     def get_settings(self):
-        """Returns a RadioSettingGroup containing one or more
+        """Returns a RadioSettings list containing one or more
         RadioSettingGroup or RadioSetting objects. These represent general
         setting knobs and dials that can be adjusted on the radio. If this
         function is implemented, the has_settings RadioFeatures flag should
diff -r 5a17f1c24b38 chirp/ft1802.py
--- a/chirp/ft1802.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft1802.py	Mon Feb 02 22:12:53 2015 -0800
@@ -24,8 +24,7 @@
 # 5. In Chirp, choose Upload to Radio.
 
 from chirp import chirp_common, bitwise, directory, yaesu_clone
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueBoolean
+from chirp.settings import *
 from textwrap import dedent
 
 MEM_FORMAT = """
diff -r 5a17f1c24b38 chirp/ft1d.py
--- a/chirp/ft1d.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft1d.py	Mon Feb 02 22:12:53 2015 -0800
@@ -20,9 +20,7 @@
 
 from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
-from chirp.settings import RadioSettingGroup, RadioSetting
-from chirp.settings import RadioSettingValueInteger, RadioSettingValueString
-from chirp.settings import RadioSettingValueList, RadioSettingValueBoolean
+from chirp.settings import *
 from textwrap import dedent
 
 MEM_FORMAT = """
@@ -1458,16 +1456,15 @@
         return menu
 
     def _get_settings(self):
-        top = RadioSettingGroup("all", "All Settings",
-                                self._get_aprs_general_settings(),
-                                self._get_aprs_rx_settings(),
-                                self._get_aprs_tx_settings(),
-                                self._get_aprs_smartbeacon(),
-                                self._get_aprs_msgs(),
-                                self._get_aprs_beacons(),
-                                self._get_dtmf_settings(),
-                                self._get_misc_settings(),
-                                self._get_scan_settings())
+        top = RadioSettings(self._get_aprs_general_settings(),
+                            self._get_aprs_rx_settings(),
+                            self._get_aprs_tx_settings(),
+                            self._get_aprs_smartbeacon(),
+                            self._get_aprs_msgs(),
+                            self._get_aprs_beacons(),
+                            self._get_dtmf_settings(),
+                            self._get_misc_settings(),
+                            self._get_scan_settings())
         return top
 
     def get_settings(self):
diff -r 5a17f1c24b38 chirp/ft60.py
--- a/chirp/ft60.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft60.py	Mon Feb 02 22:12:53 2015 -0800
@@ -16,10 +16,7 @@
 import time, os
 from chirp import chirp_common, yaesu_clone, memmap, bitwise, directory
 from chirp import errors
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat
+from chirp.settings import *
 from textwrap import dedent
 
 ACK = "\x06"
@@ -400,8 +397,7 @@
         misc = RadioSettingGroup("misc", "Miscellaneous Settings")
         mbls = RadioSettingGroup("banks", "Memory Bank Link Scan")
 
-        setmode = RadioSettingGroup("top", "Set Mode",
-                    repeater, ctcss, arts, scan, power, wires, eai, switch, misc, mbls)
+        setmode = RadioSettings(repeater, ctcss, arts, scan, power, wires, eai, switch, misc, mbls)
 
         # APO
         opts = [ "OFF" ] + [ "%0.1f" % (x * 0.5) for x in range(1, 24+1) ]
diff -r 5a17f1c24b38 chirp/ft7800.py
--- a/chirp/ft7800.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft7800.py	Mon Feb 02 22:12:53 2015 -0800
@@ -17,9 +17,7 @@
 from chirp import chirp_common, yaesu_clone, memmap, directory
 from chirp import bitwise, errors
 from textwrap import dedent
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 import os, re
 
 from collections import defaultdict
@@ -568,8 +566,8 @@
         dtmf = RadioSettingGroup("dtmf", "DTMF")
         arts = RadioSettingGroup("arts", "ARTS")
         prog = RadioSettingGroup("prog", "Programmable Buttons")
-        top = RadioSettingGroup("top", "All Settings",
-                basic, dtmf, arts, prog)
+
+        top = RadioSettings(basic, dtmf, arts, prog)
 
         basic.append( RadioSetting("priority_revert", "Priority Revert",
                 RadioSettingValueBoolean(_settings.priority_revert)))
diff -r 5a17f1c24b38 chirp/ft817.py
--- a/chirp/ft817.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft817.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,9 +18,7 @@
 
 from chirp import chirp_common, yaesu_clone, util, memmap, errors, directory
 from chirp import bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 import time, os
 from textwrap import dedent
 
@@ -763,7 +761,8 @@
         extended = RadioSettingGroup("extended", "Extended")
         antenna = RadioSettingGroup("antenna", "Antenna selection")
         panelcontr = RadioSettingGroup("panelcontr", "Panel controls")
-        top = RadioSettingGroup("top", "All Settings", basic, cw, packet,
+
+        top = RadioSettings(basic, cw, packet,
               panelcontr, panel, extended, antenna)
 
         rs = RadioSetting("ars_144", "144 ARS",
@@ -1136,7 +1135,7 @@
 
     def get_settings(self):
         top = FT817Radio.get_settings(self)
-        basic = top["basic"]
+        basic = top[0]
         rs = RadioSetting("emergency", "Emergency",
                 RadioSettingValueBoolean(self._memobj.settings.emergency))
         basic.append(rs)
diff -r 5a17f1c24b38 chirp/ft857.py
--- a/chirp/ft857.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft857.py	Mon Feb 02 22:12:53 2015 -0800
@@ -17,9 +17,7 @@
 """FT857 - FT857/US management module"""
 
 from chirp import ft817, chirp_common, errors, directory
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 import os
 from textwrap import dedent
 
@@ -525,7 +523,8 @@
         panel = RadioSettingGroup("panel", "Panel settings")
         extended = RadioSettingGroup("extended", "Extended")
         panelcontr = RadioSettingGroup("panelcontr", "Panel controls")
-        top = RadioSettingGroup("top", "All Settings", basic, cw, packet,
+
+        top = RadioSettings(basic, cw, packet,
                                 panelcontr, panel, extended)
 
         rs = RadioSetting("extended_menu", "Extended menu",
@@ -1073,7 +1072,7 @@
 
     def get_settings(self):
         top = FT857Radio.get_settings(self)
-        basic = top["basic"]
+        basic = top[0]
         rs = RadioSetting("emergency", "Emergency",
                 RadioSettingValueBoolean(self._memobj.settings.emergency))
         basic.append(rs)
diff -r 5a17f1c24b38 chirp/ft90.py
--- a/chirp/ft90.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ft90.py	Mon Feb 02 22:12:53 2015 -0800
@@ -15,9 +15,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from chirp import chirp_common, bitwise, memmap, directory, errors, util, yaesu_clone
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 import time, os, traceback, string, re
 from textwrap import dedent
 
@@ -509,7 +507,8 @@
         basic = RadioSettingGroup("basic", "Basic")
         autodial = RadioSettingGroup("autodial", "AutoDial")
         keymaps = RadioSettingGroup("keymaps", "KeyMaps")
-        top = RadioSettingGroup("top", "All Settings", basic, keymaps, autodial)
+        
+        top = RadioSettings(basic, keymaps, autodial)
         
         rs = RadioSetting("beep", "Beep",
                           RadioSettingValueBoolean(_settings.beep))
diff -r 5a17f1c24b38 chirp/ftm350.py
--- a/chirp/ftm350.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ftm350.py	Mon Feb 02 22:12:53 2015 -0800
@@ -19,8 +19,7 @@
 
 from chirp import chirp_common, yaesu_clone, directory, errors, util
 from chirp import bitwise, memmap
-from chirp.settings import RadioSettingGroup, RadioSetting
-from chirp.settings import RadioSettingValueInteger, RadioSettingValueString
+from chirp.settings import *
 
 mem_format = """
 struct mem {
@@ -380,7 +379,7 @@
         return filedata.startswith("AH033$")
 
     def get_settings(self):
-        top = RadioSettingGroup("all", "All Settings")
+        top = RadioSettings()
 
         aprs = RadioSettingGroup("aprs", "APRS")
         top.append(aprs)
diff -r 5a17f1c24b38 chirp/h777.py
--- a/chirp/h777.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/h777.py	Mon Feb 02 22:12:53 2015 -0800
@@ -21,9 +21,7 @@
 
 from chirp import chirp_common, directory, memmap
 from chirp import bitwise, errors, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean
+from chirp.settings import *
 
 DEBUG = os.getenv("CHIRP_DEBUG") and True or False
 
@@ -392,6 +390,7 @@
     def get_settings(self):
         _settings = self._memobj.settings
         basic = RadioSettingGroup("basic", "Basic Settings")
+        top = RadioSettings(basic)
 
         # TODO: Check that all these settings actually do what they
         # say they do.
@@ -472,7 +471,7 @@
                               self._memobj.settings2.timeouttimer]))
         basic.append(rs)
 
-        return basic
+        return top
 
     def set_settings(self, settings):
         for element in settings:
diff -r 5a17f1c24b38 chirp/ic2100.py
--- a/chirp/ic2100.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/ic2100.py	Mon Feb 02 22:12:53 2015 -0800
@@ -15,10 +15,7 @@
 
 from chirp import chirp_common, icf, util, directory
 from chirp import bitwise, memmap
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, InvalidValueError
+from chirp.settings import *
 
 MEM_FORMAT = """
 struct {
diff -r 5a17f1c24b38 chirp/icf.py
--- a/chirp/icf.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/icf.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,8 +18,7 @@
 import time
 
 from chirp import chirp_common, errors, util, memmap
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueBoolean
+from chirp.settings import *
 
 CMD_CLONE_OUT = 0xE2
 CMD_CLONE_IN  = 0xE3
@@ -640,17 +639,18 @@
 
 def make_speed_switch_setting(radio):
     if not radio.__class__._can_hispeed:
-        return []
+        return {}
     drvopts = RadioSettingGroup("drvopts", "Driver Options")
+    top = RadioSettings(drvopts)
     rs = RadioSetting("drv_clone_speed", "Use Hi-Speed Clone",
                       RadioSettingValueBoolean(radio._can_hispeed))
     drvopts.append(rs)
-    return drvopts
+    return top
 
 def honor_speed_switch_setting(radio, settings):
     for element in settings:
         if element.get_name() == "drvopts":
-            return honor_speed_switch_setting(radio, settings)
+            return honor_speed_switch_setting(radio, element)
         if element.get_name() == "drv_clone_speed":
             radio.__class__._can_hispeed = element.value.get_value()
             return
diff -r 5a17f1c24b38 chirp/icq7.py
--- a/chirp/icq7.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/icq7.py	Mon Feb 02 22:12:53 2015 -0800
@@ -17,10 +17,7 @@
 from chirp import chirp_common, icf, directory
 from chirp import bitwise
 from chirp.chirp_common import to_GHz, from_GHz
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-                RadioSettingValueBoolean, RadioSettingValueList, \
-                RadioSettingValueInteger, RadioSettingValueString, \
-                RadioSettingValueFloat
+from chirp.settings import *
 
 MEM_FORMAT = """
 struct {
@@ -198,7 +195,7 @@
     def get_settings(self):
         _settings = self._memobj.settings
         basic = RadioSettingGroup("basic", "Basic Settings")
-        group = RadioSettingGroup("top", "All Settings", basic)
+        group = RadioSettings(basic)
 
         rs = RadioSetting("ch", "Channel Indication Mode",
                           RadioSettingValueBoolean(_settings.ch))
diff -r 5a17f1c24b38 chirp/kenwood_live.py
--- a/chirp/kenwood_live.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/kenwood_live.py	Mon Feb 02 22:12:53 2015 -0800
@@ -25,9 +25,7 @@
     sys.path.insert(0, "..")
 
 from chirp import chirp_common, errors, directory, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueBoolean, \
-    RadioSettingValueString, RadioSettingValueList
+from chirp.settings import *
 
 DEBUG = True
 
@@ -392,7 +390,8 @@
                                   aux, tnc, save, display, dtmf)
         sky = RadioSettingGroup("sky", "SkyCommand")
         aprs = RadioSettingGroup("aprs", "APRS")
-        top = RadioSettingGroup("top", "All Settings", radio, aprs, sky)
+        
+        top = RadioSettings(radio, aprs, sky)
 
         bools = [("AMR", aprs, "APRS Message Auto-Reply"),
                  ("AIP", aux, "Advanced Intercept Point"),
diff -r 5a17f1c24b38 chirp/kguv8d.py
--- a/chirp/kguv8d.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/kguv8d.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,9 +18,7 @@
 import time
 import os
 from chirp import util, chirp_common, bitwise, memmap, errors, directory
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-                RadioSettingValueBoolean, RadioSettingValueList, \
-                RadioSettingValueInteger, RadioSettingValueString
+from chirp.settings import *
 
 if os.getenv("CHIRP_DEBUG"):
     CHIRP_DEBUG = True
@@ -677,7 +675,8 @@
         cal_grp = RadioSettingGroup("cal_grp", "Call Group")
         lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits")
         oem_grp = RadioSettingGroup("oem_grp", "OEM Info")
-        group = RadioSettingGroup("top", "All Settings", cfg_grp, vfoa_grp,
+        
+        group = RadioSettings(cfg_grp, vfoa_grp,
                         vfob_grp, key_grp, scn_grp, cal_grp, lmt_grp, oem_grp)
 
         #
diff -r 5a17f1c24b38 chirp/kyd.py
--- a/chirp/kyd.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/kyd.py	Mon Feb 02 22:12:53 2015 -0800
@@ -20,9 +20,7 @@
 
 from chirp import chirp_common, directory, memmap
 from chirp import bitwise, errors, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean
+from chirp.settings import *
 
 DEBUG = os.getenv("CHIRP_DEBUG") and True or False
 
@@ -436,6 +434,7 @@
     def get_settings(self):
         _settings = self._memobj.settings
         basic = RadioSettingGroup("basic", "Basic Settings")
+        top = RadioSettings(basic)
 
         rs = RadioSetting("tot", "Time-out timer",
                           RadioSettingValueList(TIMEOUTTIMER_LIST,
@@ -474,7 +473,7 @@
                           RadioSettingValueBoolean(_settings.save))
         basic.append(rs)
 
-        return basic
+        return top
 
     def set_settings(self, settings):
         for element in settings:
diff -r 5a17f1c24b38 chirp/leixen.py
--- a/chirp/leixen.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/leixen.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,10 +18,7 @@
 
 from chirp import chirp_common, directory, memmap, errors, util
 from chirp import bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, InvalidValueError
+from chirp.settings import *
 from textwrap import dedent
 
 if os.getenv("CHIRP_DEBUG"):
@@ -531,8 +528,7 @@
         cfg_grp = RadioSettingGroup("cfg_grp", "Basic Settings")
         adv_grp = RadioSettingGroup("adv_grp", "Advanced Settings")
         key_grp = RadioSettingGroup("key_grp", "Key Assignment")
-        group = RadioSettingGroup("top", "All Settings", cfg_grp,
-                        adv_grp, key_grp)
+        group = RadioSettings(cfg_grp, adv_grp, key_grp)
 
         #
         # Basic Settings
diff -r 5a17f1c24b38 chirp/settings.py
--- a/chirp/settings.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/settings.py	Mon Feb 02 22:12:53 2015 -0800
@@ -199,6 +199,11 @@
     def __str__(self):
         return self._current
 
+
+class RadioSettings(list):
+    def __init__(self, *groups):
+        list.__init__(self, groups)
+
 class RadioSettingGroup(object):
     """A group of settings"""
     def _validate(self, element):
@@ -244,7 +249,7 @@
 
     def __iter__(self):
         class RSGIterator:
-            """Iterator for a RadioSettingsGroup"""
+            """Iterator for a RadioSettingGroup"""
             def __init__(self, rsg):
                 self.__rsg = rsg
                 self.__i = 0
diff -r 5a17f1c24b38 chirp/th9800.py
--- a/chirp/th9800.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/th9800.py	Mon Feb 02 22:12:53 2015 -0800
@@ -17,10 +17,7 @@
 
 from chirp import bitwise, chirp_common, directory, errors, util, memmap
 import struct
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, InvalidValueError
+from chirp.settings import *
 from chirp_common import format_freq
 import os
 import time
@@ -400,8 +397,7 @@
       _bandlimits = self._memobj.bandlimits
       basic = RadioSettingGroup("basic", "Basic")
       info =  RadioSettingGroup("info", "Model Info")
-      top = RadioSettingGroup("top", "All Settings",
-                              basic, info)
+      top = RadioSettings(basic, info)
       basic.append( RadioSetting("beep", "Beep",
             RadioSettingValueBoolean(_settings.beep)))
       basic.append( RadioSetting("beep_vol", "Beep Volume",
diff -r 5a17f1c24b38 chirp/th_uvf8d.py
--- a/chirp/th_uvf8d.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/th_uvf8d.py	Mon Feb 02 22:12:53 2015 -0800
@@ -25,9 +25,7 @@
 import struct
 
 from chirp import chirp_common, bitwise, errors, directory, memmap, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 
 
 def uvf8d_identify(radio):
@@ -464,7 +462,8 @@
     def get_settings(self):
         _settings = self._memobj.settings
 
-        group = RadioSettingGroup("top", "All Settings")
+        group = RadioSettingGroup("basic", "Basic")
+        top = RadioSettings(basic)
 
         group.append(
             RadioSetting("mode", "Mode",
@@ -595,7 +594,7 @@
                          RadioSettingValueList(AB_LIST,
                                                AB_LIST[_settings.b_work_area])))
 
-        return group
+        return top
 
         group.append(
             RadioSetting("disnm", "Display Name",
diff -r 5a17f1c24b38 chirp/thuv1f.py
--- a/chirp/thuv1f.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/thuv1f.py	Mon Feb 02 22:12:53 2015 -0800
@@ -17,11 +17,7 @@
 
 from chirp import chirp_common, errors, util, directory, memmap
 from chirp import bitwise
-
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueList, RadioSettingValueBoolean, \
-    RadioSettingValueString
+from chirp.settings import *
 
 def uvf1_identify(radio):
     """Do identify handshake with TYT TH-UVF1"""
@@ -383,7 +379,8 @@
     def get_settings(self):
         _settings = self._memobj.settings
 
-        group = RadioSettingGroup("top", "All Settings")
+        group = RadioSettingGroup("basic", "Basic");
+        top = RadioSettings(group)
 
         group.append(
             RadioSetting("led", "LED Mode",
@@ -463,7 +460,7 @@
                          RadioSettingValueString(0, 6,
                                                  _filter(_settings.ponmsg))))
 
-        return group
+        return top
 
     def set_settings(self, settings):
         _settings = self._memobj.settings
diff -r 5a17f1c24b38 chirp/tk8102.py
--- a/chirp/tk8102.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/tk8102.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,9 +18,7 @@
 
 from chirp import chirp_common, directory, memmap, errors, util
 from chirp import bitwise
-from chirp.settings import RadioSettingGroup, RadioSetting
-from chirp.settings import RadioSettingValueBoolean, RadioSettingValueList
-from chirp.settings import RadioSettingValueString
+from chirp.settings import *
 
 MEM_FORMAT = """
 #seekto 0x0030;
@@ -355,7 +353,8 @@
 
     def get_settings(self):
         _mem = self._memobj
-        top = RadioSettingGroup("all", "All Settings")
+        basic = RadioSettingGroup("basic", "Basic")
+        top = RadioSettings(basic)
 
         def _f(val):
             string = ""
@@ -369,18 +368,21 @@
                              RadioSettingValueString(0, 32,
                                                      _f(_mem.messages.line1),
                                                      autopad=False))
-        top.append(line1)
+        basic.append(line1)
 
         line2 = RadioSetting("messages.line2", "Message Line 2",
                              RadioSettingValueString(0, 32,
                                                      _f(_mem.messages.line2),
                                                      autopad=False))
-        top.append(line2)
+        basic.append(line2)
 
         return top
 
     def set_settings(self, settings):
         for element in settings:
+            if not isinstance(element, RadioSetting):
+                self.set_settings(element)
+                continue
             if "." in element.get_name():
                 bits = element.get_name().split(".")
                 obj = self._memobj
diff -r 5a17f1c24b38 chirp/uv5r.py
--- a/chirp/uv5r.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/uv5r.py	Mon Feb 02 22:12:53 2015 -0800
@@ -19,10 +19,7 @@
 
 from chirp import chirp_common, errors, util, directory, memmap
 from chirp import bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, InvalidValueError
+from chirp.settings import *
 from textwrap import dedent
 
 if os.getenv("CHIRP_DEBUG"):
@@ -986,7 +983,8 @@
         _wmchannel = self._memobj.wmchannel
         basic = RadioSettingGroup("basic", "Basic Settings")
         advanced = RadioSettingGroup("advanced", "Advanced Settings")
-        group = RadioSettingGroup("top", "All Settings", basic, advanced)
+
+        group = RadioSettings(basic, advanced)
 
         rs = RadioSetting("squelch", "Carrier Squelch Level",
                           RadioSettingValueInteger(0, 9, _settings.squelch))
diff -r 5a17f1c24b38 chirp/uvb5.py
--- a/chirp/uvb5.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/uvb5.py	Mon Feb 02 22:12:53 2015 -0800
@@ -15,10 +15,7 @@
 
 import struct
 from chirp import chirp_common, directory, bitwise, memmap, errors, util
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-                RadioSettingValueBoolean, RadioSettingValueList, \
-                RadioSettingValueInteger, RadioSettingValueString, \
-                RadioSettingValueFloat
+from chirp.settings import *
 from textwrap import dedent
 
 mem_format = """
@@ -480,7 +477,8 @@
     def get_settings(self):
         _settings = self._memobj.settings
         basic = RadioSettingGroup("basic", "Basic Settings")
-        group = RadioSettingGroup("top", "All Settings", basic)
+        
+        group = RadioSettings(basic)
 
         options = ["Time", "Carrier", "Search"]
         rs = RadioSetting("scantype", "Scan Type",
diff -r 5a17f1c24b38 chirp/vx2.py
--- a/chirp/vx2.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/vx2.py	Mon Feb 02 22:12:53 2015 -0800
@@ -15,9 +15,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from chirp import chirp_common, yaesu_clone, directory, bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 import os, traceback, re
 
 if os.getenv("CHIRP_DEBUG"):
@@ -437,7 +435,7 @@
         basic = RadioSettingGroup("basic", "Basic")
         dtmf = RadioSettingGroup("dtmf", "DTMF")
         arts = RadioSettingGroup("arts", "ARTS")
-        top = RadioSettingGroup("top", "All Settings", basic, arts, dtmf)
+        top = RadioSettings(basic, arts, dtmf)
 
         options = [ "off", "30m", "1h", "3h", "5h", "8h" ]
         rs = RadioSetting("apo", "APO time (hrs)",
diff -r 5a17f1c24b38 chirp/vx3.py
--- a/chirp/vx3.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/vx3.py	Mon Feb 02 22:12:53 2015 -0800
@@ -16,9 +16,7 @@
 
 from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-    RadioSettingValueInteger, RadioSettingValueList, \
-    RadioSettingValueBoolean, RadioSettingValueString
+from chirp.settings import *
 from textwrap import dedent
 import os, re
 
@@ -529,8 +527,8 @@
         arts = RadioSettingGroup("arts", "ARTS")
         eai = RadioSettingGroup("eai", "Emergency")
         msg = RadioSettingGroup("msg", "Messages")
-        top = RadioSettingGroup("top", "All Settings",
-                basic, sound, arts, dtmf, eai, msg)
+
+        top = RadioSettings(basic, sound, arts, dtmf, eai, msg)
 
         basic.append( RadioSetting("att_wx", "Attenuation WX",
                 RadioSettingValueBoolean(_settings.att_wx)))
diff -r 5a17f1c24b38 chirp/vx8.py
--- a/chirp/vx8.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/vx8.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,9 +18,7 @@
 
 from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
-from chirp.settings import RadioSettingGroup, RadioSetting
-from chirp.settings import RadioSettingValueInteger, RadioSettingValueString
-from chirp.settings import RadioSettingValueList, RadioSettingValueBoolean
+from chirp.settings import *
 from textwrap import dedent
 
 MEM_FORMAT = """
@@ -1372,14 +1370,13 @@
         return menu
 
     def _get_settings(self):
-        top = RadioSettingGroup("all", "All Settings",
-                                self._get_aprs_general_settings(),
-                                self._get_aprs_rx_settings(),
-                                self._get_aprs_tx_settings(),
-                                self._get_aprs_smartbeacon(),
-                                self._get_dtmf_settings(),
-                                self._get_misc_settings(),
-                                self._get_scan_settings())
+        top = RadioSettings(self._get_aprs_general_settings(),
+                            self._get_aprs_rx_settings(),
+                            self._get_aprs_tx_settings(),
+                            self._get_aprs_smartbeacon(),
+                            self._get_dtmf_settings(),
+                            self._get_misc_settings(),
+                            self._get_scan_settings())
         return top
 
     def get_settings(self):
diff -r 5a17f1c24b38 chirp/wouxun.py
--- a/chirp/wouxun.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirp/wouxun.py	Mon Feb 02 22:12:53 2015 -0800
@@ -18,10 +18,7 @@
 import time
 import os
 from chirp import util, chirp_common, bitwise, memmap, errors, directory
-from chirp.settings import RadioSetting, RadioSettingGroup, \
-                RadioSettingValueBoolean, RadioSettingValueList, \
-                RadioSettingValueInteger, RadioSettingValueString, \
-                RadioSettingValueFloat
+from chirp.settings import *
 from chirp.wouxun_common import wipe_memory, do_download, do_upload
 from textwrap import dedent
 
@@ -334,7 +331,7 @@
     def get_settings(self):
         freqranges = RadioSettingGroup("freqranges", "Freq ranges")
         fm_preset = RadioSettingGroup("fm_preset", "FM Presets")
-        top = RadioSettingGroup("top", "All Settings", freqranges, fm_preset)
+        top = RadioSettings(freqranges, fm_preset)
 
         rs = RadioSetting("menu_available", "Menu Available",
                           RadioSettingValueBoolean(
@@ -1045,7 +1042,7 @@
     def get_settings(self):
         freqranges = RadioSettingGroup("freqranges", "Freq ranges")
         fm_preset = RadioSettingGroup("fm_preset", "FM Presets")
-        top = RadioSettingGroup("top", "All Settings", freqranges, fm_preset)
+        top = RadioSettings(freqranges, fm_preset)
 
         rs = RadioSetting("menu_available", "Menu Available",
                           RadioSettingValueBoolean(
@@ -1425,7 +1422,7 @@
 
     def get_settings(self):
         freqranges = RadioSettingGroup("freqranges", "Freq ranges (read only)")
-        top = RadioSettingGroup("top", "All Settings", freqranges)
+        group = RadioSettings(freqranges)
 
         rs = RadioSetting("vhf_rx_start", "vhf rx start",
                           RadioSettingValueInteger(66, 520,
@@ -1473,7 +1470,7 @@
             ( decode_freq(self._memobj.freq_ranges.vhf_rx_start) * 1000000, 
              (decode_freq(self._memobj.freq_ranges.vhf_rx_stop)+1) * 1000000)]
 
-        return top
+        return group
 
     @classmethod
     def match_model(cls, filedata, filename):
diff -r 5a17f1c24b38 chirpui/settingsedit.py
--- a/chirpui/settingsedit.py	Sun Feb 01 17:51:08 2015 -0500
+++ b/chirpui/settingsedit.py	Mon Feb 02 22:12:53 2015 -0800
@@ -16,10 +16,11 @@
 import gtk
 import gobject
 
-from chirp import chirp_common, settings
+from chirp import chirp_common
+from chirp.settings import *
 from chirpui import common, miscwidgets
 
-class RadioSettingProxy(settings.RadioSetting):
+class RadioSettingProxy(RadioSetting):
     def __init__(self, setting, editor):
         self._setting = setting
         self._editor = editor
@@ -27,40 +28,40 @@
 class SettingsEditor(common.Editor):
     def __init__(self, rthread):
         super(SettingsEditor, self).__init__(rthread)
-        self._changed = False
+
+        # The main box
         self.root = gtk.HBox(False, 0)
-        self._store = gtk.TreeStore(gobject.TYPE_STRING,
-                                    gobject.TYPE_PYOBJECT)
+
+        # The pane
+        paned = gtk.HPaned()
+        paned.show()
+        self.root.pack_start(paned, 1, 1, 0)
+    
+        # The selection tree
+        self._store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_INT)
         self._view = gtk.TreeView(self._store)
         self._view.set_size_request(150, -1)
         self._view.get_selection().connect("changed", self._view_changed_cb)
+        self._view.append_column(gtk.TreeViewColumn("", gtk.CellRendererText(), text=0))
         self._view.show()
-        self.root.pack_start(self._view, 0, 0, 0)
+        paned.pack1(self._view)
 
-        col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
-        self._view.append_column(col)
+        # The settings notebook
+        self._notebook = gtk.Notebook()
+        self._notebook.set_show_tabs(False)
+        self._notebook.set_show_border(False)
+        self._notebook.show()
+        paned.pack2(self._notebook)
 
-        self._table = gtk.Table(20, 3)
-        self._table.set_col_spacings(10)
-        self._table.show()
+        self._changed = False
+        self._settings = None
 
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        sw.add_with_viewport(self._table)
-        sw.show()
-
-        self.root.pack_start(sw, 1, 1, 1)
-
-        self._index = 0
-
-        self._top_setting_group = None
-
-        job = common.RadioJob(self._build_ui, "get_settings")
+        job = common.RadioJob(self._get_settings_cb, "get_settings")
         job.set_desc("Getting radio settings")
         self.rthread.submit(job)
 
     def _save_settings(self):
-        if self._top_setting_group is None:
+        if self._settings is None:
             return
 
         def setting_cb(result):
@@ -71,21 +72,21 @@
                 self._changed = False
 
         job = common.RadioJob(setting_cb, "set_settings",
-                              self._top_setting_group)
+                              self._settings)
         job.set_desc("Setting radio settings")
         self.rthread.submit(job)
 
     def _load_setting(self, value, widget):
-        if isinstance(value, settings.RadioSettingValueInteger):
+        if isinstance(value, RadioSettingValueInteger):
             adj = widget.get_adjustment()
             adj.configure(value.get_value(),
                           value.get_min(), value.get_max(),
                           value.get_step(), 1, 0)
-        elif isinstance(value, settings.RadioSettingValueFloat):
+        elif isinstance(value, RadioSettingValueFloat):
             widget.set_text(value.format())
-        elif isinstance(value, settings.RadioSettingValueBoolean):
+        elif isinstance(value, RadioSettingValueBoolean):
             widget.set_active(value.get_value())
-        elif isinstance(value, settings.RadioSettingValueList):
+        elif isinstance(value, RadioSettingValueList):
             model = widget.get_model()
             model.clear()
             for option in value.get_options():
@@ -93,22 +94,22 @@
             current = value.get_value()
             index = value.get_options().index(current)
             widget.set_active(index)
-        elif isinstance(value, settings.RadioSettingValueString):
+        elif isinstance(value, RadioSettingValueString):
             widget.set_text(str(value).rstrip())
         else:
             print "Unsupported widget type %s for %s" % (value.__class__,
                                                          element.get_name())
             
     def _do_save_setting(self, widget, value):
-        if isinstance(value, settings.RadioSettingValueInteger):
+        if isinstance(value, RadioSettingValueInteger):
             value.set_value(widget.get_adjustment().get_value())
-        elif isinstance(value, settings.RadioSettingValueFloat):
+        elif isinstance(value, RadioSettingValueFloat):
             value.set_value(widget.get_text())
-        elif isinstance(value, settings.RadioSettingValueBoolean):
+        elif isinstance(value, RadioSettingValueBoolean):
             value.set_value(widget.get_active())
-        elif isinstance(value, settings.RadioSettingValueList):
+        elif isinstance(value, RadioSettingValueList):
             value.set_value(widget.get_active_text())
-        elif isinstance(value, settings.RadioSettingValueString):
+        elif isinstance(value, RadioSettingValueString):
             value.set_value(widget.get_text())
         else:
             print "Unsupported widget type %s for %s" % (\
@@ -121,53 +122,62 @@
     def _save_setting(self, widget, value):
         try:
             self._do_save_setting(widget, value)
-        except settings.InvalidValueError, e:
+        except InvalidValueError, e:
             common.show_error(_("Invalid setting value: %s") % e)
 
-    def _build_ui_group(self, group):
+    def _build_ui_tab(self, group):
+
+        # The scrolled window
+        sw = gtk.ScrolledWindow()
+        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        sw.show()
+
+        # Notebook tab
+        tab = self._notebook.append_page(sw, gtk.Label(_(group.get_name())))
+
+        # Settings table
+        table = gtk.Table(len(group), 2, True)
+        table.show()
+        sw.add_with_viewport(table)
+
+        row = 0
         def pack(widget, pos):
-            self._table.attach(widget, pos, pos+1, self._index, self._index+1,
-                               xoptions=gtk.FILL, yoptions=0)
+            table.attach(widget, pos, pos+1, row, row+1,
+                               xoptions=gtk.FILL, yoptions=0, xpadding=6, ypadding=0)
 
-        def abandon(child):
-            self._table.remove(child)
-        self._table.foreach(abandon)
-
-        self._index = 0
         for element in group:
-            if not isinstance(element, settings.RadioSetting):
+            if not isinstance(element, RadioSetting):
                 continue
             label = gtk.Label(element.get_shortname())
-            label.set_alignment(1.0, 0.5)
+            label.set_alignment(-1.0, 0.5)
             label.show()
             pack(label, 0)
 
             if isinstance(element.value, list) and \
                     isinstance(element.value[0],
-                               settings.RadioSettingValueInteger):
-                arraybox = gtk.HBox(True, 3)
+                               RadioSettingValueInteger):
+                arraybox = gtk.HBox(True)
             else:
-                arraybox = gtk.VBox(True, 3)
+                arraybox = gtk.VBox(True)
             pack(arraybox, 1)
             arraybox.show()
 
             widgets = []
             for index in element.keys():
                 value = element[index]
-                if isinstance(value, settings.RadioSettingValueInteger):
+                if isinstance(value, RadioSettingValueInteger):
                     widget = gtk.SpinButton()
-                    print "Digits: %i" % widget.get_digits()
                     signal = "value-changed"
-                elif isinstance(value, settings.RadioSettingValueFloat):
+                elif isinstance(value, RadioSettingValueFloat):
                     widget = gtk.Entry()
                     signal = "focus-out-event"
-                elif isinstance(value, settings.RadioSettingValueBoolean):
+                elif isinstance(value, RadioSettingValueBoolean):
                     widget = gtk.CheckButton(_("Enabled"))
                     signal = "toggled"
-                elif isinstance(value, settings.RadioSettingValueList):
+                elif isinstance(value, RadioSettingValueList):
                     widget = miscwidgets.make_choice([], editable=False)
                     signal = "changed"
-                elif isinstance(value, settings.RadioSettingValueString):
+                elif isinstance(value, RadioSettingValueString):
                     widget = gtk.Entry()
                     signal = "changed"
                 else:
@@ -190,42 +200,35 @@
                 else:
                     widget.connect(signal, self._save_setting, value)
 
-            self._index += 1
+            row += 1
 
-    def _build_tree(self, group, parent):
+        return tab
+
+    def _build_ui_group(self, group, parent):
+        
+        tab = self._build_ui_tab(group)
+        
         iter = self._store.append(parent)
-        self._store.set(iter, 0, group.get_shortname(), 1, group)
+        self._store.set(iter, 0, group.get_shortname(), 1, tab)
         
-        if self._set_default is None:
-            # If we haven't found the first page with actual settings on it
-            # yet, then look for one here
-            for element in group:
-                if isinstance(element, settings.RadioSetting):
-                    self._set_default = self._store.get_path(iter), group
-                    break
+        for element in group:
+            if not isinstance(element, RadioSetting):
+                self._build_ui_group(element, iter)
 
-        for element in group:
-            if not isinstance(element, settings.RadioSetting):
-                self._build_tree(element, iter)
+    def _build_ui(self, settings):
+        if not isinstance(settings, list):
+            raise Exception("Invalid Radio Settings")
+            return
+
+        self._settings = settings
+        for group in settings:
+            self._build_ui_group(group, None)
         self._view.expand_all()
 
-    def _build_ui_real(self, group):
-        if not isinstance(group, settings.RadioSettingGroup):
-            print "Toplevel is not a group"
-            return
-
-        self._set_default = None
-        self._top_setting_group = group
-        self._build_tree(group, None)
-        self._view.set_cursor(self._set_default[0])
-        self._build_ui_group(self._set_default[1])
-
-    def _build_ui(self, group):
-        gobject.idle_add(self._build_ui_real, group)
+    def _get_settings_cb(self, settings):
+        gobject.idle_add(self._build_ui, settings)
 
     def _view_changed_cb(self, selection):
         (lst, iter) = selection.get_selected()
-        group, = self._store.get(iter, 1)
-
-        if group:
-            self._build_ui_group(group)
+        tab, = self._store.get(iter, 1)
+        self._notebook.set_current_page(tab)
\ No newline at end of file
diff -r 5a17f1c24b38 tests/run_tests
--- a/tests/run_tests	Sun Feb 01 17:51:08 2015 -0500
+++ b/tests/run_tests	Mon Feb 02 22:12:53 2015 -0800
@@ -24,7 +24,7 @@
 
 from chirp import CHIRP_VERSION
 from chirp import *
-from chirp import chirp_common, directory, generic_csv, import_logic, memmap
+from chirp import chirp_common, directory, generic_csv, import_logic, memmap, settings
 from chirp import errors
 
 TESTS = {}
@@ -523,13 +523,15 @@
 
 TESTS["Edges"] = TestCaseEdges
 
-
 class TestCaseSettings(TestCase):
     def __str__(self):
         return "Settings"
 
     def do_get_settings(self, rf):
-        self._wrapper.do("get_settings")
+        lst = self._wrapper.do("get_settings")
+        if not isinstance(lst, list):
+	    raise TestFailedError("Invalid Radio Settings")
+        self._wrapper.do("set_settings", lst)
 
     def run(self):
         rf = self._wrapper.do("get_features")
@@ -537,7 +539,7 @@
         if not rf.has_settings:
             raise TestSkippedError("Settings not supported")
 
-        self.do_get_settings(rf)
+	self.do_get_settings(rf)
 
         return []
 
