# HG changeset patch # User Dan Smith dsmith@danplanet.com # Date 1361137561 28800 # Node ID 82e79201a24bc1ad9f5b17012d6e6d7d58e271e8 # Parent 3aeeaedfb5f721bf72c26a416b0a053f96173831 Make the UI enforce reasonable tone modes when tone columns are changed
This ensures that if the user touches one of the tone columns, that the tone mode changes to an appropriate value so as not to confuse them.
Fixes #591
diff -r 3aeeaedfb5f7 -r 82e79201a24b chirp/chirp_common.py --- a/chirp/chirp_common.py Sat Feb 16 21:30:58 2013 -0500 +++ b/chirp/chirp_common.py Sun Feb 17 13:46:01 2013 -0800 @@ -51,11 +51,11 @@
CROSS_MODES = [ "Tone->Tone", + "DTCS->", + "->DTCS", "Tone->DTCS", "DTCS->Tone", - "DTCS->", "->Tone", - "->DTCS", "DTCS->DTCS", ]
diff -r 3aeeaedfb5f7 -r 82e79201a24b chirpui/mainapp.py --- a/chirpui/mainapp.py Sat Feb 16 21:30:58 2013 -0500 +++ b/chirpui/mainapp.py Sun Feb 17 13:46:01 2013 -0800 @@ -1173,6 +1173,9 @@ def do_toggle_autorpt(self, action): CONF.set_bool("autorpt", action.get_active(), "memedit")
+ def do_toggle_no_smart_tmode(self, action): + CONF.set_bool("no_smart_tmode", not action.get_active(), "memedit") + def do_toggle_developer(self, action): conf = config.get() conf.set_bool("developer", action.get_active(), "state") @@ -1262,6 +1265,8 @@ self.do_toggle_report(_action) elif action == "autorpt": self.do_toggle_autorpt(_action) + elif action == "no_smart_tmode": + self.do_toggle_no_smart_tmode(_action) elif action == "developer": self.do_toggle_developer(_action) elif action in ["cut", "copy", "paste", "delete", @@ -1311,6 +1316,7 @@ <menu action="view"> <menuitem action="columns"/> <menuitem action="hide_unused"/> + <menuitem action="no_smart_tmode"/> <menu action="viewdeveloper"> <menuitem action="devshowraw"/> <menuitem action="devdiffraw"/> @@ -1397,10 +1403,12 @@ hu = conf.get_bool("hide_unused", "memedit") ro = conf.get_bool("autorpt", "memedit") dv = conf.get_bool("developer", "state") + st = not conf.get_bool("no_smart_tmode", "memedit")
toggles = [\ ('report', None, _("Report statistics"), None, None, self.mh, re), ('hide_unused', None, _("Hide Unused Fields"), None, None, self.mh, hu), + ('no_smart_tmode', None, _("Smart Tone Modes"), None, None, self.mh, st), ('autorpt', None, _("Automatic Repeater Offset"), None, None, self.mh, ro), ('developer', None, _("Enable Developer Functions"), None, None, self.mh, dv), ] diff -r 3aeeaedfb5f7 -r 82e79201a24b chirpui/memedit.py --- a/chirpui/memedit.py Sat Feb 16 21:30:58 2013 -0500 +++ b/chirpui/memedit.py Sun Feb 17 13:46:01 2013 -0800 @@ -201,6 +201,52 @@
return new
+ def ed_tone_field(self, _foo, path, new, col): + if self._config.get_bool("no_smart_tmode"): + return + + iter = self.store.get_iter(path) + + # Python scoping hurts us here, so store this as a list + # that we can modify, instead of helpful variables :( + modes = list(self.store.get(iter, + self.col(_("Tone Mode")), + self.col(_("Cross Mode")))) + + def _tm(*tmodes): + if modes[0] not in tmodes: + modes[0] = tmodes[0] + self.store.set(iter, self.col(_("Tone Mode")), modes[0]) + def _cm(*cmodes): + if modes[0] == "Cross" and modes[1] not in cmodes: + modes[1] = cmodes[0] + self.store.set(iter, self.col(_("Cross Mode")), modes[1]) + + if col == self.col(_("DTCS Code")): + _tm("DTCS", "Cross") + _cm(*tuple([x for x in chirp_common.CROSS_MODES + if x.startswith("DTCS->")])) + elif col == self.col(_("DTCS Rx Code")): + _tm("DTCS", "Cross") + _cm(*tuple([x for x in chirp_common.CROSS_MODES + if x.endswith("->DTCS")])) + elif col == self.col(_("DTCS Pol")): + _tm("DTCS", "Cross") + _cm(*tuple([x for x in chirp_common.CROSS_MODES + if "DTCS" in x])) + elif col == self.col(_("Tone")): + _tm("Tone", "Cross") + _cm(*tuple([x for x in chirp_common.CROSS_MODES + if x.startswith("Tone->")])) + elif col == self.col(_("ToneSql")): + _tm("TSQL", "Cross") + _cm(*tuple([x for x in chirp_common.CROSS_MODES + if x.endswith("->Tone")])) + elif col == self.col(_("Cross Mode")): + _tm("Cross") + + return new + def _get_cols_to_hide(self, iter): tmode, duplex = self.store.get(iter, self.col(_("Tone Mode")), @@ -260,6 +306,12 @@ _("Frequency") : self.ed_freq, _("Duplex") : self.ed_duplex, _("Offset") : self.ed_offset, + _("Tone") : self.ed_tone_field, + _("ToneSql"): self.ed_tone_field, + _("DTCS Code"): self.ed_tone_field, + _("DTCS Rx Code"): self.ed_tone_field, + _("DTCS Pol"): self.ed_tone_field, + _("Cross Mode"): self.ed_tone_field, }
if funcs.has_key(cap): diff -r 3aeeaedfb5f7 -r 82e79201a24b tests/unit/test_memedit_edits.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/unit/test_memedit_edits.py Sun Feb 17 13:46:01 2013 -0800 @@ -0,0 +1,57 @@ +import mox +from tests.unit import base + +__builtins__["_"] = lambda s: s + +from chirpui import memedit + + +class TestEdits(base.BaseTest): + def _test_tone_column_change(self, col, + ini_tmode='', ini_cmode='', + exp_tmode=None, exp_cmode=None): + editor = self.mox.CreateMock(memedit.MemoryEditor) + editor.col = lambda x: x + editor.store = self.mox.CreateMockAnything() + editor.store.get_iter('path').AndReturn('iter') + editor.store.get('iter', 'Tone Mode', 'Cross Mode').AndReturn( + (ini_tmode, ini_cmode)) + if exp_tmode: + editor.store.set('iter', 'Tone Mode', exp_tmode) + if exp_cmode and col != 'Cross Mode': + editor.store.set('iter', 'Cross Mode', exp_cmode) + self.mox.ReplayAll() + memedit.MemoryEditor.ed_tone_field(editor, None, 'path', None, col) + + def _test_auto_tone_mode(self, col, exp_tmode, exp_cmode): + # No tmode -> expected + self._test_tone_column_change(col, exp_tmode=exp_tmode) + # Expected tmode does not re-set tmode + self._test_tone_column_change(col, ini_tmode=exp_tmode) + # Invalid tmode -> expected + self._test_tone_column_change(col, ini_tmode="foo", + exp_tmode=exp_tmode) + # Expected cmode does not re-set cmode + self._test_tone_column_change(col, ini_tmode="Cross", + ini_cmode=exp_cmode) + # Invalid cmode -> expected + self._test_tone_column_change(col, ini_tmode="Cross", + ini_cmode="foo", exp_cmode=exp_cmode) + + def test_auto_tone_mode_tone(self): + self._test_auto_tone_mode('Tone', 'Tone', 'Tone->Tone') + + def test_auto_tone_mode_tsql(self): + self._test_auto_tone_mode('ToneSql', 'TSQL', 'Tone->Tone') + + def test_auto_tone_mode_dtcs(self): + self._test_auto_tone_mode('DTCS Code', 'DTCS', 'DTCS->') + + def test_auto_tone_mode_dtcs_rx(self): + self._test_auto_tone_mode('DTCS Rx Code', 'DTCS', '->DTCS') + + def test_auto_tone_mode_dtcs_pol(self): + self._test_auto_tone_mode('DTCS Pol', 'DTCS', 'DTCS->') + + def test_auto_tone_mode_cross(self): + self._test_auto_tone_mode('Cross Mode', 'Cross', 'Tone->Tone')