[chirp_devel] [PATCH 0 of 3] [RFC] Radio Mods Interface
Hi all,
This is the (fixed up) RFC mod patch set that I initially started to show Rick. It includes some basic plumbing, UI, and stubs for the VX7 radio (which is, I think, the only one for which we know about any mods). After doing this, I realized that maybe it would be better to not call this a "mod" interface, but more of a general "radio settings" interface, allowing a way to provide radio-specific feature support. For anything that is common across models, I'd still like something formalized like everything else, but this could be a way to support one-offs.
Thoughts?
--Dan KK7DS
# HG changeset patch # User Dan Smith dsmith@danplanet.com # Date 1302106344 25200 # Node ID 3d3a44d2309b969e24571e436eb5b7b706095500 # Parent 99e058729af64f4836e2d9ac6009e9a116f8b0f5 Add basic RadioMod object
diff -r 99e058729af6 -r 3d3a44d2309b chirp/chirp_common.py --- a/chirp/chirp_common.py Tue Apr 05 12:36:16 2011 -0700 +++ b/chirp/chirp_common.py Wed Apr 06 09:12:24 2011 -0700 @@ -492,6 +492,7 @@ "has_name" : BOOLEAN, "has_ctone" : BOOLEAN, "has_cross" : BOOLEAN, + "has_mods" : BOOLEAN,
# Attributes "valid_modes" : [], @@ -542,6 +543,7 @@ self.has_tuning_step = True self.has_ctone = True self.has_cross = False + self.has_mods = False
self.valid_modes = list(MODES) self.valid_tmodes = [] @@ -840,3 +842,66 @@ if ret != 1: ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__tid(), 0) raise Exception("Failed to signal thread!") + +class RadioMod: + def __init__(self, name, current): + self._name = name + self._current = current + self._new = current + self._doc = None + + def get_name(self): + return self._name + + def get_current_value(self): + return self._current + + def get_new_value(self): + return self._new + + def set_new_value(self, value): + pass + + def set_doc(self, doc): + self._doc = doc + + def get_doc(self): + return self._doc + + def is_changed(self): + return self._current == self._new + +class RadioModInt(RadioMod): + _format = "%i" + + def set_range(self, low, high): + self._low = low + self._high = high + + def set_new_value(self, value): + value = int(value) + + if value <= self._high and value >= self._low: + self._new = value + else: + raise ValueError("Invalid value") + + def set_display_format(self, format): + self._format = format + + def get_display_format(self): + return self._format + +class RadioModOpt(RadioMod): + def set_options(self, options): + self._options = options + + def get_options(self): + return self._options + + def set_new_value(self, value): + if value in self._options: + self._new = value + else: + raise ValueError("Invalid value") +
# HG changeset patch # User Dan Smith dsmith@danplanet.com # Date 1302106729 25200 # Node ID f51cc15cd52dfce7a958af5b1708178e7c73adcb # Parent 3d3a44d2309b969e24571e436eb5b7b706095500 Add basic UI elements for modifications
diff -r 3d3a44d2309b -r f51cc15cd52d chirpui/editorset.py --- a/chirpui/editorset.py Wed Apr 06 09:12:24 2011 -0700 +++ b/chirpui/editorset.py Wed Apr 06 09:18:49 2011 -0700 @@ -21,7 +21,7 @@
from chirp import chirp_common, directory, csv, xml from chirpui import memedit, dstaredit, bankedit, common, importdialog -from chirpui import inputdialog +from chirpui import inputdialog, modedit
class EditorSet(gtk.VBox): __gsignals__ = { @@ -69,6 +69,11 @@ else: self.banked = None
+ if self.radio.get_features().has_mods: + self.moded = modedit.ModEditor(self.rthread) + else: + self.moded = None + lab = gtk.Label("Memories") self.tabs.append_page(self.memedit.root, lab) self.memedit.root.show() @@ -85,6 +90,12 @@ self.banked.root.show() self.banked.connect("changed", self.banks_changed)
+ if self.moded: + lab = gtk.Label("Mods") + self.tabs.append_page(self.moded.root, lab) + self.moded.root.show() + #self.moded.connect("changed", self.mods_changed) + self.pack_start(self.tabs) self.tabs.show()
@@ -275,8 +286,9 @@
def tab_selected(self, notebook, foo, pagenum): # Quick hack for D-STAR editor - if pagenum == 1: - self.dstared.focus() + #if pagenum == 1: + # self.dstared.focus() + pass
def set_read_only(self, read_only=True): self.memedit.set_read_only(read_only) diff -r 3d3a44d2309b -r f51cc15cd52d chirpui/modedit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirpui/modedit.py Wed Apr 06 09:18:49 2011 -0700 @@ -0,0 +1,115 @@ +#!/usr/bin/python +# +# Copyright 2010 Dan Smith dsmith@danplanet.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +import gtk +import gobject + +from chirp import chirp_common +from chirpui import common, miscwidgets + +def enforce_format(entry, new, length, pos, format): + formats = { + "X" : "0123456789ABCDEF", + "i" : "0123456789", + } + + for i in new: + if i.upper() not in formats[format]: + entry.stop_emission("insert-text") + +class ModificationEditor: + def __init__(self, radio, mod): + self._radio = radio + self._mod = mod + + def build_ui(self): + pass + + def _build_label(self): + l = gtk.Label(self._mod.get_name()) + l.show() + return l + + def _set_mod(self, button): + self._mod.set_new_value(self._get_value()) + self._radio.set_mod(self._mod) + + def _build_set(self): + b = gtk.Button("Set") + b.connect("clicked", self._set_mod) + b.show() + return b + +class OptionModificationEditor(ModificationEditor): + def _get_value(self): + return self.__c.get_active_text() + + def build_ui(self): + self.__c = miscwidgets.make_choice(self._mod.get_options(), + False, self._mod.get_current_value()) + self.__c.show() + + return self._build_label(), self.__c, self._build_set() + +class IntegerModificationEditor(ModificationEditor): + def _get_value(self): + base = { + "X" : 16, + "i" : 10, + } + + return int(self.__n.get_text(), + base[self._mod.get_display_format()[-1]]) + + def build_ui(self): + self.__n = gtk.Entry() + self.__n.connect("insert-text", enforce_format, + self._mod.get_display_format()[-1]) + v = self._mod.get_display_format() % self._mod.get_current_value() + self.__n.set_text(v) + self.__n.show() + + return self._build_label(), self.__n, self._build_set() + +class ModEditor(common.Editor): + def __init__(self, rthread): + common.Editor.__init__(self) + self.rthread = rthread + + self.root = gtk.Table(5, 3) + + xopts = gtk.FILL + yopts = 0 + + row = 0 + for mod in rthread.radio.get_mods(): + if isinstance(mod, chirp_common.RadioModOpt): + e = OptionModificationEditor(self.rthread.radio, mod) + elif isinstance(mod, chirp_common.RadioModInt): + e = IntegerModificationEditor(self.rthread.radio, mod) + else: + continue + + col = 0 + for widget in e.build_ui(): + self.root.attach(widget, col, col+1, row, row+1, + xopts, yopts, 3, 1) + col += 1 + row += 1 + + def focus(self): + pass
# HG changeset patch # User Dan Smith dsmith@danplanet.com # Date 1302106741 25200 # Node ID 1dad3b1387f43306f46416af90f0979d55a5ce07 # Parent f51cc15cd52dfce7a958af5b1708178e7c73adcb Add stubs for VX7 mods
diff -r f51cc15cd52d -r 1dad3b1387f4 chirp/vx7.py --- a/chirp/vx7.py Wed Apr 06 09:18:49 2011 -0700 +++ b/chirp/vx7.py Wed Apr 06 09:19:01 2011 -0700 @@ -120,6 +120,7 @@ rf.memory_bounds = (1, 450) rf.can_odd_split = True rf.has_ctone = False + rf.has_mods = True return rf
def get_raw_memory(self, number): @@ -219,3 +220,26 @@ @classmethod def match_model(cls, filedata): return len(filedata) == cls._memsize + + def get_mods(self): + band = chirp_common.RadioModOpt("Band Mode", "Unmodified") + band.set_options(["Unmodified", "MARS/CAP", "Freeband"]) + + cpu = chirp_common.RadioModInt("CPU Version", 0x0100) + cpu.set_range(0x0000, 0xFFFF) + cpu.set_display_format("%04X") + + return [band, cpu] + + def set_mod(self, mod): + if mod.get_name() == "Band Mode": + val = mod.get_new_value() + # val is now one of the three options, bang the bits + # accordingly + print "Band mode is now: %s" % val + elif mod.get_name() == "CPU Version": + val = mod.get_new_value() + byte1 = (val & 0xFF00) >> 8 + byte2 = (val & 0x00FF) + # byte1 and byte2 can now be set in place + print "CPU version is now %02x,%02x" % (byte1, byte2)
participants (1)
-
Dan Smith