<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'># HG changeset patch<br># User K. Arvanitis <<a href="mailto:kosta@alumni.uvic.ca">kosta@alumni.uvic.ca</a>><br># Date 1421911819 28800<br># Wed Jan 21 23:30:19 2015 -0800<br># Node ID a14b91de7d5390bad00ec450f0546531b6bb268d<br># Parent 9ca5e99e7552a667b362e6f6dac67212fbbc6a34<br>[FT-60] Adding Support for Settings to Yaesu FT-60<BR>Added support for most of the basic (but not all) settings avail. on<br>the FT-60.<BR>Note: some settings map to the memory bank and are therefore<br>not included in this list.<BR>Note: the list of settings and categories was taken from the<br>user manual for this radio.<BR>Tested against the specific revision model no. FT-60R.<BR>Feature #1759<BR>diff -r 9ca5e99e7552 -r a14b91de7d53 chirp/ft60.py<br>--- a/chirp/ft60.py Sat Jan 17 10:10:54 2015 -0600<br>+++ b/chirp/ft60.py Wed Jan 21 23:30:19 2015 -0800<br>@@ -13,9 +13,13 @@<br> # You should have received a copy of the GNU General Public License<br> # along with this program. If not, see <<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.<br> <br>-import time<br>+import time, os<br> from chirp import chirp_common, yaesu_clone, memmap, bitwise, directory<br> from chirp import errors<br>+from chirp.settings import RadioSetting, RadioSettingGroup, \<br>+ RadioSettingValueInteger, RadioSettingValueList, \<br>+ RadioSettingValueBoolean, RadioSettingValueString, \<br>+ RadioSettingValueFloat<br> from textwrap import dedent<br> <br> ACK = "\x06"<br>@@ -128,6 +132,78 @@<br> <br> <br> MEM_FORMAT = """<br>+#seekto 0x0024;<br>+struct {<br>+ u8 apo;<br>+ u8 x25:3,<br>+ tot:5;<br>+ u8 x26;<br>+ u8 x27;<br>+ u8 x28:4,<br>+ rf_sql:4;<br>+ u8 x29:4,<br>+ int_cd:4;<br>+ u8 x2A:4,<br>+ int_mr:4;<br>+ u8 x2B:5,<br>+ lock:3;<br>+ u8 x2C:5,<br>+ dt_dly:3;<br>+ u8 x2D:7,<br>+ dt_spd:1;<br>+ u8 ar_bep;<br>+ u8 x2F:6,<br>+ lamp:2;<br>+ u8 x30:5,<br>+ bell:3;<br>+ u8 x31:5,<br>+ rxsave:3;<br>+ u8 x32;<br>+ u8 x33;<br>+ u8 x34;<br>+ u8 x35;<br>+ u8 x36;<br>+ u8 x37;<br>+ u8 wx_alt:1,<br>+ x38_1:3,<br>+ ar_int:1,<br>+ x38_5:3;<br>+ u8 x39:3,<br>+ ars:1,<br>+ vfo_bnd:1,<br>+ dcs_nr:2,<br>+ ssrch:1;<br>+ u8 pri_rvt:1,<br>+ x3A_1:1,<br>+ beep_sc:1,<br>+ edg_bep:1,<br>+ beep_key:1,<br>+ inet:2,<br>+ x3A_7:1;<br>+ u8 x3B_0:5,<br>+ scn_md:1,<br>+ x3B_6:2;<br>+ u8 x3C_0:2,<br>+ rev_hm:1,<br>+ mt_cl:1<br>+ resume:2,<br>+ txsave:1,<br>+ pag_abk:1;<br>+ u8 x3D_0:1,<br>+ scn_lmp:1,<br>+ x3D_2:1,<br>+ bsy_led:1,<br>+ x3D_4:1,<br>+ tx_led:1,<br>+ x3D_6:2;<br>+ u8 x3E_0:2,<br>+ bclo:1,<br>+ x3E_3:5;<br>+} settings;<br>+ <br>+#seekto 0x09E;<br>+ul16 mbs;<br>+<br> #seekto 0x0248;<br> struct {<br> u8 used:1,<br>@@ -198,6 +274,10 @@<br> bank = chirp_common.Bank(self, "%i" % (i + 1), "Bank %i" % (i + 1))<br> bank.index = i<br> banks.append(bank)<br>+<br>+ #mbs = (self._radio._memobj.mbs >> i) & 1<br>+ #print "Bank %i: mbs: %i " % (i, mbs) <br>+<br> return banks<br> <br> def add_memory_to_mapping(self, memory, bank):<br>@@ -277,6 +357,7 @@<br> rf.can_odd_split = True<br> rf.has_ctone = False<br> rf.has_bank = True<br>+ rf.has_settings = True<br> rf.has_dtcs_polarity = False<br> <br> return rf<br>@@ -309,6 +390,229 @@<br> def process_mmap(self):<br> self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)<br> <br>+ def get_settings(self):<br>+ _settings = self._memobj.settings<br>+<br>+ repeater = RadioSettingGroup("repeater", "Repeater Settings")<br>+ ctcss = RadioSettingGroup("ctcss", "CTCSS/DSC/DTMF Settings")<br>+ arts = RadioSettingGroup("arts", "ARTS Settings")<br>+ scan = RadioSettingGroup("scan", "Scan Settings")<br>+ power = RadioSettingGroup("power", "Power Saver Settings")<br>+ wires = RadioSettingGroup("wires", "WiRES(tm) Settings")<br>+ eai = RadioSettingGroup("eai", "EAI/EPCS Settings")<br>+ switch = RadioSettingGroup("switch", "Switch/Knob Settings")<br>+ misc = RadioSettingGroup("misc", "Miscellaneous Settings")<br>+<br>+ setmode = RadioSettingGroup("top", "Set Mode",<br>+ repeater, ctcss, arts, scan, power, wires, eai, switch, misc)<br>+<br>+ # APO<br>+ opts = [ "OFF" ] + [ "%0.1f" % (x * 0.5) for x in range(1, 24+1) ]<br>+ misc.append( RadioSetting("apo", "Automatic Power Off",<br>+ RadioSettingValueList(opts, opts[_settings.apo])))<br>+<br>+ # AR.BEP<br>+ opts = [ "OFF" ] + [ "INRANG" ] + [ "ALWAYS" ]<br>+ arts.append( RadioSetting("ar_bep", "ARTS Beep",<br>+ RadioSettingValueList(opts, opts[_settings.ar_bep])))<br>+<br>+ # AR.INT<br>+ opts = ["25 SEC"] + [ "15 SEC" ]<br>+ arts.append( RadioSetting("ar_int", "ARTS Polling Interval",<br>+ RadioSettingValueList(opts, opts[_settings.ar_int])))<br>+<br>+ # ARS<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ repeater.append( RadioSetting("ars", "Automatic Repeater Shift",<br>+ RadioSettingValueList(opts, opts[_settings.ars])))<br>+<br>+ # BCLO<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ misc.append( RadioSetting("bclo", "Bush Channel Lock-Out",<br>+ RadioSettingValueList(opts, opts[_settings.bclo])))<br>+<br>+ # BEEP<br>+ opts = [ "OFF" ] + [ "KEY" ] + [ "KEY+SC" ]<br>+ rs = RadioSetting("beep_key", "Enable the Beeper",<br>+ RadioSettingValueList(opts, opts[_settings.beep_key + _settings.beep_sc]))<br>+ def apply_beep(s, obj):<br>+ setattr(obj, "beep_key", (int(s.value) & 1) or ((int(s.value) >> 1) & 1))<br>+ setattr(obj, "beep_sc", (int(s.value) >> 1) & 1)<br>+ rs.set_apply_callback(apply_beep, self._memobj.settings);<br>+ switch.append(rs)<br>+<br>+ # BELL<br>+ opts = [ "OFF" ] + [ "1T" ] + [ "3T" ] + [ "5T" ] + [ "8T" ] + [ "CONT" ]<br>+ ctcss.append( RadioSetting("bell", "Bell Repetitions",<br>+ RadioSettingValueList(opts, opts[_settings.bell])))<br>+<br>+ # BSY.LED<br>+ opts = [ "ON" ] + [ "OFF" ]<br>+ misc.append( RadioSetting("bsy_led", "Busy LED",<br>+ RadioSettingValueList(opts, opts[_settings.bsy_led])))<br>+<br>+ # DCS.NR<br>+ opts = [ "TR/X N" ] + [ "RX R" ] + [ "TX R" ] + [ "T/RX R" ]<br>+ ctcss.append( RadioSetting("dcs_nr", "\"Inverted\" DCS Code Decoding",<br>+ RadioSettingValueList(opts, opts[_settings.dcs_nr])))<br>+<br>+ # DT.DLY<br>+ opts = [ "50 MS" ] + [ "100 MS" ] + [ "250 MS" ] + [ "450 MS" ] + \<br>+ [ "750 MS" ]+ [ "1000 MS" ]<br>+ ctcss.append( RadioSetting("dt_dly", "DTMF Autodialer Delay Time",<br>+ RadioSettingValueList(opts, opts[_settings.dt_dly])))<br>+<br>+ # DT.SPD<br>+ opts = [ "50 MS" ] + [ "100 MS" ]<br>+ ctcss.append( RadioSetting("dt_spd", "DTMF Autodialer Sending Speed",<br>+ RadioSettingValueList(opts, opts[_settings.dt_spd])))<br>+<br>+ # EDG.BEP<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ misc.append( RadioSetting("edg_bep", "Band Edge Beeper",<br>+ RadioSettingValueList(opts, opts[_settings.edg_bep])))<br>+<br>+ # I.NET<br>+ opts = [ "OFF" ] + [ "COD" ]+ [ "MEM" ]<br>+ rs = RadioSetting("inet", "Internet Link Connection",<br>+ RadioSettingValueList(opts, opts[_settings.inet - 1]))<br>+ def apply_inet(s, obj):<br>+ setattr(obj, s.get_name(), int(s.value) + 1)<br>+ rs.set_apply_callback(apply_inet, self._memobj.settings);<br>+ wires.append(rs)<br>+<br>+ # INT.CD<br>+ opts = [ "CODE 0" ] + [ "CODE 1" ] + [ "CODE 2" ] + [ "CODE 3" ] + [ "CODE 4" ] + \<br>+ [ "CODE 5" ] + [ "CODE 6" ] + [ "CODE 7" ] + [ "CODE 8" ] + [ "CODE 9" ] + \<br>+ [ "CODE A" ] + [ "CODE B" ] + [ "CODE C" ] + [ "CODE D" ] + [ "CODE E" ] + [ "CODE F" ]<br>+ wires.append( RadioSetting("int_cd", "Access Number for WiRES(TM)",<br>+ RadioSettingValueList(opts, opts[_settings.int_cd])))<br>+<br>+ # INT.MR<br>+ opts = [ "d1" ] + [ "d2" ] + [ "d3" ] + [ "d4" ] + [ "d5" ] + \<br>+ [ "d6" ] + [ "d7" ] + [ "d8" ] + [ "d9" ]<br>+ wires.append( RadioSetting("int_mr", "Access Number (DTMF) for Non-WiRES(TM)",<br>+ RadioSettingValueList(opts, opts[_settings.int_mr])))<br>+<br>+ # LAMP<br>+ opts = [ "KEY" ] + [ "5SEC" ] + [ "TOGGLE" ]<br>+ switch.append( RadioSetting("lamp", "Lamp Mode",<br>+ RadioSettingValueList(opts, opts[_settings.lamp])))<br>+<br>+ # LOCK<br>+ opts = [ "LK KEY" ] + [ "LKDIAL" ] + [ "LK K+D" ] + [ "LK PTT" ] + [ "LP P+K" ] + \<br>+ [ "LK P+D" ] + [ "LK ALL" ]<br>+ rs = RadioSetting("lock", "Control Locking",<br>+ RadioSettingValueList(opts, opts[_settings.lock - 1]))<br>+ def apply_lock(s, obj):<br>+ setattr(obj, s.get_name(), int(s.value) + 1)<br>+ rs.set_apply_callback(apply_lock, self._memobj.settings);<br>+ switch.append(rs)<br>+<br>+ # M/T-CL<br>+ opts = [ "MONI" ] + [ "T-CALL" ]<br>+ switch.append( RadioSetting("mt_cl", "MONI Switch Function",<br>+ RadioSettingValueList(opts, opts[_settings.mt_cl])))<br>+<br>+ # PAG.ABK<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ eai.append( RadioSetting("pag_abk", "Paging Answer Back",<br>+ RadioSettingValueList(opts, opts[_settings.pag_abk])))<br>+<br>+ # RESUME<br>+ opts = [ "TIME" ] + [ "HOLD" ] + [ "BUSY" ]<br>+ scan.append( RadioSetting("resume", "Scan Resume Mode",<br>+ RadioSettingValueList(opts, opts[_settings.resume])))<br>+<br>+ # REV/HM<br>+ opts = [ "REV" ] + [ "HOME" ]<br>+ switch.append( RadioSetting("rev_hm", "HM/RV Key Function",<br>+ RadioSettingValueList(opts, opts[_settings.rev_hm])))<br>+<br>+ # RF.SQL<br>+ opts = [ "OFF" ] + [ "S-1" ] + [ "S-2" ] + [ "S-3" ] + [ "S-4" ] + \<br>+ [ "S-5" ] + [ "S-6" ] + [ "S-8" ] + [ "S-FULL" ]<br>+ misc.append( RadioSetting("rf_sql", "RF Squelch Threshold",<br>+ RadioSettingValueList(opts, opts[_settings.rf_sql])))<br>+<br>+ # PRI.RVT<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ scan.append( RadioSetting("pri_rvt", "Priority Revert",<br>+ RadioSettingValueList(opts, opts[_settings.pri_rvt])))<br>+<br>+ # RXSAVE<br>+ opts = [ "OFF" ] + [ "200 MS" ] + [ "300 MS" ] + [ "500 MS" ] + [ "1 S" ] + [ "2 S" ]<br>+ power.append( RadioSetting("rxsave", "Receive Mode Batery Savery Interval",<br>+ RadioSettingValueList(opts, opts[_settings.rxsave])))<br>+<br>+ # S.SRCH<br>+ opts = [ "SINGLE" ] + [ "CONT" ]<br>+ misc.append( RadioSetting("ssrch", "Smart Search Sweep Mode",<br>+ RadioSettingValueList(opts, opts[_settings.ssrch])))<br>+<br>+ # SCN.MD<br>+ opts = [ "MEM" ] + [ "ONLY" ]<br>+ scan.append( RadioSetting("scn_md", "Memory Scan Channel Selection Mode",<br>+ RadioSettingValueList(opts, opts[_settings.scn_md])))<br>+<br>+ # SCN.LMP<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ scan.append( RadioSetting("scn_lmp", "Scan Lamp",<br>+ RadioSettingValueList(opts, opts[_settings.scn_lmp])))<br>+<br>+ # TOT<br>+ opts = [ "OFF" ] + [ "%dMIN" % (x) for x in range(1, 30+1) ]<br>+ misc.append( RadioSetting("tot", "Timeout Timer",<br>+ RadioSettingValueList(opts, opts[_settings.tot])))<br>+<br>+ # TX.LED<br>+ opts = [ "ON" ] + [ "OFF" ]<br>+ misc.append( RadioSetting("tx_led", "TX LED",<br>+ RadioSettingValueList(opts, opts[_settings.tx_led])))<br>+<br>+ # TXSAVE<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ power.append( RadioSetting("txsave", "Transmitter Battery Saver",<br>+ RadioSettingValueList(opts, opts[_settings.txsave])))<br>+<br>+ # VFO.BND<br>+ opts = [ "BAND" ] + [ "ALL" ]<br>+ misc.append( RadioSetting("vfo_bnd", "VFO Band Edge Limiting",<br>+ RadioSettingValueList(opts, opts[_settings.vfo_bnd])))<br>+<br>+ # WX.ALT<br>+ opts = [ "OFF" ] + [ "ON" ]<br>+ scan.append( RadioSetting("wx_alt", "Weather Alert Scan",<br>+ RadioSettingValueList(opts, opts[_settings.wx_alt])))<br>+<br>+ return setmode<br>+<br>+ def set_settings(self, uisettings):<br>+ _settings = self._memobj.settings<br>+ for element in uisettings:<br>+ if not isinstance(element, RadioSetting):<br>+ self.set_settings(element)<br>+ continue<br>+ if not element.changed():<br>+ continue<br>+<br>+ try:<br>+ name = element.get_name()<br>+ value = element.value<br>+ obj = getattr(_settings, name)<br>+<br>+ if element.has_apply_callback():<br>+ print "Using apply callback"<br>+ element.run_apply_callback()<br>+ else:<br>+ setattr(_settings, name, value)<br>+<br>+ if os.getenv("CHIRP_DEBUG"):<br>+ print "Setting %s: %s <= %s" % (name, obj, element.value)<br>+ except Exception, e:<br>+ print element.get_name()<br>+ raise<br>+<br> def get_raw_memory(self, number):<br> return repr(self._memobj.memory[number - 1]) + \<br> repr(self._memobj.flags[(number - 1) / 4]) + \<br>diff -r 9ca5e99e7552 -r a14b91de7d53 chirpui/settingsedit.py<br>--- a/chirpui/settingsedit.py Sat Jan 17 10:10:54 2015 -0600<br>+++ b/chirpui/settingsedit.py Wed Jan 21 23:30:19 2015 -0800<br>@@ -45,6 +45,7 @@<br> self._table.show()<br> <br> sw = gtk.ScrolledWindow()<br>+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)<br> sw.add_with_viewport(self._table)<br> sw.show()<br> <br>@@ -144,9 +145,9 @@<br> if isinstance(element.value, list) and \<br> isinstance(element.value[0],<br> settings.RadioSettingValueInteger):<br>- arraybox = gtk.HBox(3, True)<br>+ arraybox = gtk.HBox(True, 3)<br> else:<br>- arraybox = gtk.VBox(3, True)<br>+ arraybox = gtk.VBox(True, 3)<br> pack(arraybox, 1)<br> arraybox.show()<br> <br><BR>                                            </div></body>
</html>