# HG changeset patch
# User K. Arvanitis <kosta@alumni.uvic.ca>
# Date 1422338533 28800
# Parent  b25606106a9c0cd78f3cc5f602475da64cde081d
[PATCH] User Defined Memory Prototype

diff -r b25606106a9c -r 089b8f520583 chirp/chirp_common.py
--- a/chirp/chirp_common.py	Wed Jan 21 23:30:19 2015 -0800
+++ b/chirp/chirp_common.py	Mon Jan 26 22:02:13 2015 -0800
@@ -252,6 +252,9 @@
     # or an empty list if none
     extra = []
 
+    # User memory
+    user = {}
+
     def __init__(self):
         self.freq = 0
         self.number = 0
@@ -691,6 +694,7 @@
         "valid_dtcs_pols"     : [],
         "valid_dtcs_codes"    : [],
         "valid_special_chans" : [],
+        "valid_user_mem"      : [],
 
         "has_sub_devices"     : BOOLEAN,
         "memory_bounds"       : (0, 0),
@@ -813,6 +817,9 @@
                   "Supported DTCS codes")
         self.init("valid_special_chans", [],
                   "Supported special channel names")
+        self.init("valid_user_mem", [],
+                  "Supported user defined memory")
+
 
         self.init("has_sub_devices", False,
                   "Indicates that the radio behaves as two semi-independent " +
@@ -1042,6 +1049,10 @@
         should be True and get_settings() must be implemented as well."""
         pass
 
+    def get_user_mem(self):
+        pass
+
+
 class FileBackedRadio(Radio):
     """A file-backed radio stores its data in a file"""
     FILE_EXTENSION = "img"
diff -r b25606106a9c -r 089b8f520583 chirp/ft60.py
--- a/chirp/ft60.py	Wed Jan 21 23:30:19 2015 -0800
+++ b/chirp/ft60.py	Mon Jan 26 22:02:13 2015 -0800
@@ -20,6 +20,7 @@
     RadioSettingValueInteger, RadioSettingValueList, \
     RadioSettingValueBoolean, RadioSettingValueString, \
     RadioSettingValueFloat
+from gobject import *
 from textwrap import dedent
 
 ACK = "\x06"
@@ -354,6 +355,16 @@
         rf.valid_name_length = 6
         rf.valid_modes = ["FM", "NFM", "AM"]
         rf.valid_bands = [(108000000, 520000000), (700000000, 999990000)]
+
+        rf.valid_user_mem = [ ("Float", TYPE_DOUBLE, "float", 0.0, None), \
+            ("Float Choice", TYPE_DOUBLE, "float_choice", 0.0, [0.0, 1.0, 2.0]), \
+            ("String", TYPE_STRING, "string", "", None), \
+            ("String Choice", TYPE_STRING, "string_choice", "", ["A", "B"]), \
+            ("Int", TYPE_INT, "int", "", None), \
+            ("Int Choice", TYPE_INT, "int_choice", "", [1, 2]), \
+            ("Bool", TYPE_BOOLEAN, "bool", True, None)
+            ]
+
         rf.can_odd_split = True
         rf.has_ctone = False
         rf.has_bank = True
@@ -649,6 +660,14 @@
         if _nam.use_name and _nam.valid:
             mem.name = _decode_name(_nam.name).rstrip()
 
+        mem.user["float"] = 0.5
+        mem.user["float_choice"] = 1.0
+        mem.user["string"] = "Hello"
+        mem.user["string_choice"] = "A"
+        mem.user["int"] = 1
+        mem.user["int_choice"] = 2
+        mem.user["bool"] = True
+
         return mem
 
     def set_memory(self, mem):
diff -r b25606106a9c -r 089b8f520583 chirp/uv5r.py
--- a/chirp/uv5r.py	Wed Jan 21 23:30:19 2015 -0800
+++ b/chirp/uv5r.py	Mon Jan 26 22:02:13 2015 -0800
@@ -23,6 +23,7 @@
     RadioSettingValueInteger, RadioSettingValueList, \
     RadioSettingValueBoolean, RadioSettingValueString, \
     RadioSettingValueFloat, InvalidValueError
+from gobject import *
 from textwrap import dedent
 
 if os.getenv("CHIRP_DEBUG"):
@@ -663,6 +664,11 @@
         else:
             rf.valid_bands = normal_bands
         rf.memory_bounds = (0, 127)
+
+        rf.valid_user_mem = [ ("BCL", TYPE_BOOLEAN, "bcl", False, None), \
+            ("PTT ID", TYPE_STRING, "pttid", PTTID_LIST[0], PTTID_LIST), \
+            ("PTT ID Code", TYPE_STRING, "scode", PTTIDCODE_LIST[0], PTTIDCODE_LIST)]
+
         return rf
 
     @classmethod
@@ -810,6 +816,10 @@
 
         mem.mode = _mem.wide and "FM" or "NFM"
 
+        mem.user["bcl"] = _mem.bcl
+        mem.user["pttid"] = PTTID_LIST[_mem.pttid]
+        mem.user["scode"] = PTTIDCODE_LIST[_mem.scode]
+        
         mem.extra = RadioSettingGroup("Extra", "extra")
 
         rs = RadioSetting("bcl", "BCL",
diff -r b25606106a9c -r 089b8f520583 chirpui/memedit.py
--- a/chirpui/memedit.py	Wed Jan 21 23:30:19 2015 -0800
+++ b/chirpui/memedit.py	Mon Jan 26 22:02:13 2015 -0800
@@ -27,7 +27,8 @@
     TYPE_STRING, \
     TYPE_BOOLEAN, \
     TYPE_PYOBJECT, \
-    TYPE_INT64
+    TYPE_INT64, \
+    TYPE_ENUM
 import gobject
 import pickle
 import os
@@ -36,9 +37,6 @@
 from chirpui import bandplans
 from chirp import chirp_common, errors, directory, import_logic
 
-def handle_toggle(_, path, store, col):
-    store[path][col] = not store[path][col]    
-
 def handle_ed(_, iter, new, store, col):
     old, = store.get(iter, col)
     if old != new:
@@ -321,6 +319,11 @@
         hide_cols = self._get_cols_to_hide(iter)
         self.store.set(iter, self.col("_hide_cols"), hide_cols)
 
+
+    def toggled(self, rend, path, cap):
+        new = not self.store[path][self.col(cap)]
+        self.edited(rend, path, new, cap)
+
     def edited(self, rend, path, new, cap):
         if self.read_only:
             common.show_error(_("Unable to make changes to this model"))
@@ -331,7 +334,7 @@
         and self.store.get(iter, self.col(_("Frequency")))[0] == 0:
             print _("Editing new item, taking defaults")
             self.insert_new(iter)
-
+        
         colnum = self.col(cap)
         funcs = {
             _("Loc") : self.ed_loc,
@@ -414,7 +417,6 @@
             if extd:
                 val = extd
 
-
         return val
 
     def render(self, _, rend, model, iter, colnum):
@@ -963,11 +965,11 @@
             rend = _rend()
             rend.connect('editing-started', self.cell_editing_started)
             rend.connect('editing-canceled', self.cell_editing_stopped)
-            rend.connect('edited', self.cell_editing_stopped)
+            #rend.connect('edited', self.cell_editing_stopped)
 
-            if _type == TYPE_BOOLEAN:
-                #rend.set_property("activatable", True)
-                #rend.connect("toggled", handle_toggle, self.store, i)
+            if _type == TYPE_BOOLEAN and _rend != gtk.CellRendererCombo:
+                rend.set_property("activatable", True)
+                rend.connect("toggled", self.toggled, _cap)
                 col = gtk.TreeViewColumn(_cap, rend, active=i, sensitive=filled)
             elif _rend == gtk.CellRendererCombo:
                 if isinstance(self.choices[_cap], gtk.ListStore):
@@ -1073,6 +1075,9 @@
                        self.col(_("Skip")), memory.skip,
                        self.col(_("Comment")), memory.comment)
 
+        for _cap, _type, _name, _def, _choices in self._features.valid_user_mem:
+            self.store.set(iter, self.col(_cap), memory.user[_name])
+
         hide = self._get_cols_to_hide(iter)
         self.store.set(iter, self.col("_hide_cols"), hide)
 
@@ -1130,6 +1135,9 @@
         mem.comment = vals[self.col(_("Comment"))]
         mem.empty = not vals[self.col("_filled")]
 
+        for _cap, _type, _name, _def, _choices in self._features.valid_user_mem:
+            mem.user[_name] = vals[self.col(_cap)]
+
     def _get_memory(self, iter):
         vals = self.store.get(iter, *range(0, len(self.cols)))
         mem = chirp_common.Memory()
@@ -1288,6 +1296,8 @@
     def __init__(self, rthread):
         super(MemoryEditor, self).__init__(rthread)
 
+        self.cols = list(self.cols)
+        self.choices = dict(self.choices)
         self.defaults = dict(self.defaults)
 
         self._config = config.get("memedit")
@@ -1307,8 +1317,6 @@
         self.lo_limit_adj = self.hi_limit_adj = None
         self.store = self.view = None
 
-        self.__cache_columns()
-
         self._features = self.rthread.radio.get_features()
 
         (min, max) = self._features.memory_bounds
@@ -1331,6 +1339,24 @@
         if self.defaults[_("Mode")] not in self._features.valid_modes:
             self.defaults[_("Mode")] = self._features.valid_modes[0]
 
+        self.choices["Mode"] = self._features.valid_modes
+
+        if self._features["valid_user_mem"]:
+        
+            for _cap, _type, _name, _def, _choices in self._features.valid_user_mem:
+                index = self.cols.index(("_filled", TYPE_BOOLEAN, None))
+                if not _choices:
+                    if _type == TYPE_BOOLEAN:
+                        self.cols.insert(index, (_cap, _type, gtk.CellRendererToggle))
+                    else:
+                        self.cols.insert(index, (_cap, _type, gtk.CellRendererText))
+                else:
+                    self.cols.insert(index, (_cap, _type, gtk.CellRendererCombo))
+                    self.choices[_cap] = _choices
+                self.defaults[_cap] = _def
+
+        self.__cache_columns()
+
         vbox = gtk.VBox(False, 2)
         vbox.pack_start(self.make_controls(min, max), 0, 0, 0)
         vbox.pack_start(self.make_editor(), 1, 1, 1)
@@ -1338,8 +1364,6 @@
 
         self.prefill()
         
-        self.choices["Mode"] = self._features.valid_modes
-
         self.root = vbox
 
         self.prefill()
diff -r b25606106a9c -r 089b8f520583 chirpui/settingsedit.py
--- a/chirpui/settingsedit.py	Wed Jan 21 23:30:19 2015 -0800
+++ b/chirpui/settingsedit.py	Mon Jan 26 22:02:13 2015 -0800
@@ -35,7 +35,6 @@
         self._view.set_size_request(150, -1)
         self._view.get_selection().connect("changed", self._view_changed_cb)
         self._view.show()
-        self.root.pack_start(self._view, 0, 0, 0)
 
         col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
         self._view.append_column(col)
@@ -49,7 +48,12 @@
         sw.add_with_viewport(self._table)
         sw.show()
 
-        self.root.pack_start(sw, 1, 1, 1)
+        pane = gtk.HPaned()
+        pane.add1(self._view)
+        pane.add2(sw)
+        pane.show()
+
+        self.root.pack_start(pane, 1, 1, 1)
 
         self._index = 0
 
