[chirp_devel] [PATCH 7 of 7] UI support for the new banks model

Dan Smith
Tue Feb 7 20:08:33 PST 2012


# HG changeset patch
# User Dan Smith <dsmith at danplanet.com>
# Date 1328673811 28800
# Node ID 8aeaa94466783d5a68c0a74cdb0cc8f39a526bf2
# Parent  4023f8be12127e2931858891f8f950e950554117
UI support for the new banks model

diff -r 4023f8be1212 -r 8aeaa9446678 chirpui/bankedit.py
--- a/chirpui/bankedit.py	Tue Feb 07 20:03:31 2012 -0800
+++ b/chirpui/bankedit.py	Tue Feb 07 20:03:31 2012 -0800
@@ -16,20 +16,40 @@
 import gtk
 import gobject
 
+from gobject import TYPE_INT, TYPE_STRING, TYPE_BOOLEAN
+
+from chirp import chirp_common
 from chirpui import common, miscwidgets
 
-class BankEditor(common.Editor):
+class BankNamesJob(common.RadioJob):
+    def __init__(self, editor, cb):
+        common.RadioJob.__init__(self, cb, None)
+        self.__editor = editor
+
+    def execute(self, radio):
+        self.__editor.banks = []
+
+        bm = radio.get_bank_model()
+        banks = bm.get_banks()
+        for bank in banks:
+            self.__editor.banks.append((bank, bank.get_name()))
+
+        gobject.idle_add(self.cb, *self.cb_args)
+
+class BankNameEditor(common.Editor):
     def refresh(self):
-        def set_banks(banks):
-            i = ord("A")
-            for bank in banks:
-                self.listw.set_item(chr(i), chr(i), str(bank))
-                i += 1
+        def got_banks():
+            self._keys = []
+            for bank, name in self.banks:
+                self._keys.append(bank.get_index())
+                self.listw.set_item(bank.get_index(),
+                                    bank.get_index(),
+                                    name)
 
             self.listw.connect("item-set", self.bank_changed)
 
-        job = common.RadioJob(set_banks, "get_banks")
-        job.set_desc(_("Retrieving bank list"))
+        job = BankNamesJob(self, got_banks)
+        job.set_desc(_("Retrieving bank information"))
         self.rthread.submit(job)
 
     def get_bank_list(self):
@@ -44,8 +64,15 @@
         def cb(*args):
             self.emit("changed")
 
-        job = common.RadioJob(cb, "set_banks", self.get_bank_list())
-        job.set_desc(_("Setting bank list"))
+        name = self.listw.get_item(key)[2]
+        bank, oldname = self.banks[self._keys.index(key)]
+
+        def trigger_changed(*args):
+            self.emit("changed")
+
+        job = common.RadioJob(trigger_changed, "set_name", name)
+        job.set_target(bank)
+        job.set_desc(_("Setting name on bank"))
         self.rthread.submit(job)
 
         return True
@@ -64,10 +91,203 @@
         self.listw.set_sort_column(1, -1)
         self.listw.show()
 
+        self.banks = []
+
         sw = gtk.ScrolledWindow()
         sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
         sw.add_with_viewport(self.listw)
 
         self.root = sw
+        self._loaded = False
+
+    def focus(self):
+        if self._loaded:
+            return
 
         self.refresh()
+        self._loaded = True
+
+class MemoryBanksJob(common.RadioJob):
+    def __init__(self, cb, number):
+        common.RadioJob.__init__(self, cb, None)
+        self.__number = number
+
+    def execute(self, radio):
+        mem = radio.get_memory(self.__number)
+        if mem.empty:
+            banks = []
+            indexes = []
+        else:
+            bm = radio.get_bank_model()
+            banks = bm.get_memory_banks(mem)
+            indexes = []
+            if isinstance(bm, chirp_common.BankIndexInterface):
+                for bank in banks:
+                    indexes.append(bm.get_memory_index(mem, bank))
+        self.cb(mem, banks, indexes, *self.cb_args)
+            
+class BankMembershipEditor(common.Editor):
+    def _number_to_path(self, number):
+        return (number - self._rf.memory_bounds[0],)
+
+    def _toggled_cb(self, rend, path, colnum):
+        # The bank index is the column number, minus the 3 label columns
+        bank, name = self.banks[colnum - len(self._cols)]
+        loc, = self._store.get(self._store.get_iter(path), 0)
+
+        if rend.get_active():
+            # Changing from True to False
+            fn = "remove_memory_from_bank"
+        else:
+            # Changing from False to True
+            fn = "add_memory_to_bank"
+
+        def do_refresh_memory(*args):
+            # Step 2: Update our notion of the memory's bank information
+            self.refresh_memory(loc)
+
+        def do_bank_adjustment(memory):
+            # Step 1: Do the bank add/remove
+            job = common.RadioJob(do_refresh_memory, fn, memory, bank)
+            job.set_target(self.rthread.radio.get_bank_model())
+            job.set_desc(_("Updating bank information "
+                           "for memory {num}").format(num=memory.number))
+            self.rthread.submit(job)
+
+        # Step 0: Fetch the memory
+        job = common.RadioJob(do_bank_adjustment, "get_memory", loc)
+        job.set_desc(_("Getting memory {num}").format(num=loc))
+        self.rthread.submit(job)
+
+    def _index_edited_cb(self, rend, path, new):
+        loc, = self._store.get(self._store.get_iter(path), 0)
+        
+        def refresh_memory(*args):
+            self.refresh_memory(loc)
+
+        def set_index(banks, memory):
+            # Step 2: Set the index
+            job = common.RadioJob(refresh_memory, "set_memory_index",
+                                  memory, banks[0], int(new))
+            job.set_target(self.rthread.radio.get_bank_model())
+            job.set_desc(_("Setting index "
+                           "for memory {num}").format(num=memory.number))
+            self.rthread.submit(job)
+
+        def get_bank(memory):
+            # Step 1: Get the first/only bank
+            job = common.RadioJob(set_index, "get_memory_banks", memory)
+            job.set_cb_args(memory)
+            job.set_target(self.rthread.radio.get_bank_model())
+            job.set_desc(_("Getting bank for "
+                           "memory {num}").format(num=memory.number))
+            self.rthread.submit(job)
+
+        # Step 0: Get the memory
+        job = common.RadioJob(get_bank, "get_memory", loc)
+        job.set_desc(_("Getting memory {num}").format(num=loc))
+        self.rthread.submit(job)
+            
+    def __init__(self, rthread):
+        common.Editor.__init__(self)
+        self.rthread = rthread
+        self._rf = rthread.radio.get_features()
+
+        self._cols = [
+            (_("Loc"),       TYPE_INT,     gtk.CellRendererText, ),
+            (_("Frequency"), TYPE_STRING,  gtk.CellRendererText, ),
+            (_("Name"),      TYPE_STRING,  gtk.CellRendererText, ),
+            (_("Index"),     TYPE_INT,     gtk.CellRendererText, ),
+            ]
+        
+        cols = list(self._cols)
+
+        for i in range(0, self.rthread.radio.get_bank_model().get_num_banks()):
+            label = "Bank %i" % (i+1)
+            cols.append((label, TYPE_BOOLEAN, gtk.CellRendererToggle))
+
+        self._store = gtk.ListStore(*tuple([y for x,y,z in cols]))
+        self._view = gtk.TreeView(self._store)
+
+        colnum = 0
+        for label, dtype, rtype in cols:
+            rend = rtype()
+            if dtype == TYPE_BOOLEAN:
+                rend.set_property("activatable", True)
+                rend.connect("toggled", self._toggled_cb, colnum)
+                col = gtk.TreeViewColumn(label, rend, active=colnum)
+            else:
+                col = gtk.TreeViewColumn(label, rend, text=colnum)
+
+            self._view.append_column(col)
+            if colnum == 3:
+                rend.set_property("editable", True)
+                rend.connect("edited", self._index_edited_cb)
+                col.set_visible(self._rf.has_bank_index)
+            colnum += 1
+
+        sw = gtk.ScrolledWindow()
+        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        sw.add(self._view)
+        self._view.show()
+
+        for i in range(*self._rf.memory_bounds):
+            iter = self._store.append()
+            self._store.set(iter, 0, i, 1, 0, 2, "", 3, 0)
+
+        self.root = sw
+        self._loaded = False
+
+    def refresh_memory(self, number):
+        def got_mem(memory, banks, indexes):
+            iter = self._store.get_iter(self._number_to_path(memory.number))
+            row = [0, memory.number,
+                   1, chirp_common.format_freq(memory.freq),
+                   2, memory.name,
+                   # Hack for only one index right now
+                   3, indexes and indexes[0] or 0,
+                   ]
+            for i in range(0, len(self.banks)):
+                row.append(i + len(self._cols))
+                row.append(self.banks[i][0] in banks)
+                
+            self._store.set(iter, *tuple(row))
+
+        job = MemoryBanksJob(got_mem, number)
+        job.set_desc(_("Getting bank information "
+                       "for memory {num}").format(num=number))
+        self.rthread.submit(job)
+
+    def refresh_all_memories(self):
+        for i in range(*self._rf.memory_bounds):
+            self.refresh_memory(i)
+
+    def refresh_banks(self, and_memories=False):
+        def got_banks():
+            for i in range(0, len(self.banks)):
+                col = self._view.get_column(i + len(self._cols))
+                bank, name = self.banks[i]
+                if name:
+                    col.set_title(name)
+                else:
+                    col.set_title("(%s)" % i)
+            if and_memories:
+                self.refresh_all_memories()
+
+        job = BankNamesJob(self, got_banks)
+        job.set_desc(_("Getting bank information"))
+        self.rthread.submit(job)
+
+    def focus(self):
+        if self._loaded:
+            return
+
+        self.refresh_banks(True)
+
+        self._loaded = True
+
+    def memories_changed(self):
+        self._loaded = False
+
+    def banks_changed(self):
+        self.refresh_banks()
diff -r 4023f8be1212 -r 8aeaa9446678 chirpui/common.py
--- a/chirpui/common.py	Tue Feb 07 20:03:31 2012 -0800
+++ b/chirpui/common.py	Tue Feb 07 20:03:31 2012 -0800
@@ -94,7 +94,8 @@
         try:
             func = getattr(self.target, self.func)
         except AttributeError, e:
-            print "No such radio function `%s'" % self.func
+            print "No such radio function `%s' in %s" % (self.func,
+                                                         self.target)
             return
 
         self._execute(self.target, func)
diff -r 4023f8be1212 -r 8aeaa9446678 chirpui/editorset.py
--- a/chirpui/editorset.py	Tue Feb 07 20:03:31 2012 -0800
+++ b/chirpui/editorset.py	Tue Feb 07 20:03:31 2012 -0800
@@ -59,43 +59,57 @@
         self.tabs.connect("switch-page", self.tab_selected)
         self.tabs.set_tab_pos(gtk.POS_LEFT)
 
+        self.editors = {
+            "memedit"      : None,
+            "dstar"        : None,
+            "bank_names"   : None,
+            "bank_members" : None,
+            }
+
         if isinstance(self.radio, chirp_common.IcomDstarSupport):
-            self.memedit = memedit.DstarMemoryEditor(self.rthread)
-            self.dstared = dstaredit.DStarEditor(self.rthread)
+            self.editors["memedit"] = memedit.DstarMemoryEditor(self.rthread)
+            self.editors["dstar"] = dstaredit.DStarEditor(self.rthread)
         else:
-            print "Starting memedit"
-            self.memedit = memedit.MemoryEditor(self.rthread)
-            print "Started"
-            self.dstared = None
+            self.editors["memedit"] = memedit.MemoryEditor(self.rthread)
 
-        self.memedit.connect("usermsg", lambda e, m: self.emit("usermsg", m))
+        self.editors["memedit"].connect("usermsg",
+                                        lambda e, m: self.emit("usermsg", m))
 
-        if self.radio.get_features().has_bank_index:
-            self.banked = bankedit.BankEditor(self.rthread)
-        else:
-            self.banked = None
+        rf = self.radio.get_features()
+
+        if rf.has_bank:
+            self.editors["bank_members"] = \
+                bankedit.BankMembershipEditor(self.rthread)
+        
+        if rf.has_bank_names:
+            self.editors["bank_names"] = bankedit.BankNameEditor(self.rthread)
 
         lab = gtk.Label(_("Memories"))
-        self.tabs.append_page(self.memedit.root, lab)
-        self.memedit.root.show()
+        self.tabs.append_page(self.editors["memedit"].root, lab)
+        self.editors["memedit"].root.show()
 
-        if self.dstared:
+        if self.editors["dstar"]:
             lab = gtk.Label(_("D-STAR"))
-            self.tabs.append_page(self.dstared.root, lab)
-            self.dstared.root.show()
-            self.dstared.connect("changed", self.dstar_changed)
+            self.tabs.append_page(self.editors["dstar"].root, lab)
+            self.editors["dstar"].root.show()
+            self.editors["dstar"].connect("changed", self.dstar_changed)
 
-        if self.banked:
+        if self.editors["bank_names"]:
+            lab = gtk.Label(_("Bank Names"))
+            self.tabs.append_page(self.editors["bank_names"].root, lab)
+            self.editors["bank_names"].root.show()
+            self.editors["bank_names"].connect("changed", self.banks_changed)
+
+        if self.editors["bank_members"]:
             lab = gtk.Label(_("Banks"))
-            self.tabs.append_page(self.banked.root, lab)
-            self.banked.root.show()
-            self.banked.connect("changed", self.banks_changed)
+            self.tabs.append_page(self.editors["bank_members"].root, lab)
+            self.editors["bank_members"].root.show()
 
         self.pack_start(self.tabs)
         self.tabs.show()
 
         # pylint: disable-msg=E1101
-        self.memedit.connect("changed", self.editor_changed)
+        self.editors["memedit"].connect("changed", self.editor_changed)
 
         self.label = self.text_label = None
         self.make_label()
@@ -145,16 +159,17 @@
 
     def dstar_changed(self, *args):
         print "D-STAR editor changed"
-        self.memedit.set_urcall_list(self.dstared.editor_ucall.get_callsigns())
-        self.memedit.set_repeater_list(self.dstared.editor_rcall.get_callsigns())
-        self.memedit.prefill()
+        memedit = self.editors["memedit"]
+        dstared = self.editors["dstar"]
+        memedit.set_urcall_list(dstared.editor_ucall.get_callsigns())
+        memedit.set_repeater_list(dstared.editor_rcall.get_callsigns())
+        memedit.prefill()
         self.modified = True
         self.update_tab()
 
     def banks_changed(self, *args):
         print "Banks changed"
-        self.memedit.set_bank_list(self.banked.get_bank_list())
-        self.memedit.prefill()
+        self.editors["bank_members"].banks_changed()
         self.modified = True
         self.update_tab()
 
@@ -162,6 +177,8 @@
         if not isinstance(self.radio, chirp_common.LiveRadio):
             self.modified = True
             self.update_tab()
+        if self.editors["bank_members"]:
+            self.editors["bank_members"].memories_changed()
 
     def get_tab_label(self):
         return self.label
@@ -190,7 +207,7 @@
         print "Imported %i" % count
         if count > 0:
             self.editor_changed()
-            gobject.idle_add(self.memedit.prefill)
+            gobject.idle_add(self.editors["memedit"].prefill)
 
         dst_rthread._qunlock()
 
@@ -289,23 +306,22 @@
         mem.freq = 146010000
 
         def cb(*args):
-            gobject.idle_add(self.memedit.prefill)
+            gobject.idle_add(self.editors["memedit"].prefill)
 
         job = common.RadioJob(cb, "set_memory", mem)
         job.set_desc(_("Priming memory"))
         self.rthread.submit(job)
 
     def tab_selected(self, notebook, foo, pagenum):
-        pages = ["memory", "dstar", "banks"]
-
-        # Quick hack for D-STAR editor
-        if pagenum == 1:
-            self.dstared.focus()
-
-        self.emit("editor-selected", pages[pagenum])
+        widget = notebook.get_nth_page(pagenum)
+        for k,v in self.editors.items():
+            if v and v.root == widget:
+                v.focus()
+                self.emit("editor-selected", k)
+                break
 
     def set_read_only(self, read_only=True):
-        self.memedit.set_read_only(read_only)
+        self.editors["memedit"].set_read_only(read_only)
 
     def prepare_close(self):
-        self.memedit.prepare_close()
+        self.editors["memedit"].prepare_close()
diff -r 4023f8be1212 -r 8aeaa9446678 chirpui/mainapp.py
--- a/chirpui/mainapp.py	Tue Feb 07 20:03:31 2012 -0800
+++ b/chirpui/mainapp.py	Tue Feb 07 20:03:31 2012 -0800
@@ -162,7 +162,7 @@
 
     def ev_editor_selected(self, editorset, editortype):
         mappings = {
-            "memory" : ["view", "edit"],
+            "memedit" : ["view", "edit"],
             }
 
         for _editortype, actions in mappings.items():
diff -r 4023f8be1212 -r 8aeaa9446678 chirpui/memedit.py
--- a/chirpui/memedit.py	Tue Feb 07 20:03:31 2012 -0800
+++ b/chirpui/memedit.py	Tue Feb 07 20:03:31 2012 -0800
@@ -114,8 +114,6 @@
         (_("Power")     , TYPE_STRING,  gtk.CellRendererCombo, ),
         (_("Tune Step") , TYPE_FLOAT,   gtk.CellRendererCombo, ),
         (_("Skip")      , TYPE_STRING,  gtk.CellRendererCombo, ),
-        (_("Bank")      , TYPE_STRING,  gtk.CellRendererCombo, ),
-        (_("Bank Index"), TYPE_INT,     gtk.CellRendererText,  ),
         ("_filled"      , TYPE_BOOLEAN, None,                  ),
         ("_hide_cols"   , TYPE_PYOBJECT,None,                  ),
         ("_extd"        , TYPE_STRING,  None,                  ),
@@ -136,8 +134,6 @@
         _("Tune Step") : 5.0,
         _("Tone Mode") : "",
         _("Skip")      : "",
-        _("Bank")      : "",
-        _("Bank Index"): 0,
         }
 
     choices = {
@@ -241,10 +237,9 @@
         return new
 
     def _get_cols_to_hide(self, iter):
-        tmode, duplex, bank = self.store.get(iter,
-                                             self.col(_("Tone Mode")),
-                                             self.col(_("Duplex")),
-                                             self.col(_("Bank")))
+        tmode, duplex = self.store.get(iter,
+                                       self.col(_("Tone Mode")),
+                                       self.col(_("Duplex")))
 
         hide = []
 
@@ -267,9 +262,6 @@
         if duplex == "" or duplex == "(None)":
             hide += [self.col(_("Offset"))]
 
-        if bank == "":
-            hide += [self.col(_("Bank Index"))]
-
         return hide
 
     def maybe_hide_cols(self, iter):
@@ -923,18 +915,6 @@
                 self.rthread.submit(job, 2)
 
     def _set_memory(self, iter, memory):
-        try:
-            if memory.bank is None:
-                bank = ""
-            else:
-                pathstr = "%i" % (memory.bank + 1)
-                bi = self.choices[_("Bank")].get_iter_from_string(pathstr)
-                bank, = self.choices[_("Bank")].get(bi, 1)
-        except Exception, e:
-            common.log_exception()
-            print "Unable to get bank: %s" % e
-            bank = ""
-
         self.store.set(iter,
                        self.col("_filled"), not memory.empty,
                        self.col(_("Loc")), memory.number,
@@ -952,9 +932,7 @@
                        self.col(_("Mode")), memory.mode,
                        self.col(_("Power")), memory.power or "",
                        self.col(_("Tune Step")), memory.tuning_step,
-                       self.col(_("Skip")), memory.skip,
-                       self.col(_("Bank")), bank,
-                       self.col(_("Bank Index")), memory.bank_index)
+                       self.col(_("Skip")), memory.skip)
 
         hide = self._get_cols_to_hide(iter)
         self.store.set(iter, self.col("_hide_cols"), hide)
@@ -987,34 +965,6 @@
             iter = self.store.iter_next(iter)
 
     def _set_mem_vals(self, mem, vals, iter):
-        def get_bank_index(name):
-            bidx = 0
-            banks = self.choices[_("Bank")]
-            iter = banks.get_iter_first()
-            iter = banks.iter_next(iter)
-            while iter:
-                _bank, = banks.get(iter, 1)
-                if name == _bank:
-                    break
-                iter = banks.iter_next(iter)
-                bidx += 1
-
-            return bidx
-
-        bank = vals[self.col(_("Bank"))]
-        if bank is "":
-            bidx = None
-            bank_index = vals[self.col(_("Bank Index"))]
-        else:
-            bidx = get_bank_index(bank)
-            if vals[self.col(_("Bank Index"))] == -1 and \
-                    self._features.has_bank_index:
-                bank_index = self.rthread.radio.get_available_bank_index(bidx)
-                print "Chose %i index for bank %s" % (bank_index, bank)
-                self.store.set(iter, self.col(_("Bank Index")), bank_index)
-            else:
-                bank_index = vals[self.col(_("Bank Index"))]
-
         power_levels = {"" : None}
         for i in self._features.valid_power_levels:
             power_levels[str(i)] = i
@@ -1036,8 +986,6 @@
         mem.power = power_levels[vals[self.col(_("Power"))]]
         mem.tuning_step = vals[self.col(_("Tune Step"))]
         mem.skip = vals[self.col(_("Skip"))]
-        mem.bank = bidx
-        mem.bank_index = bank_index
         mem.empty = not vals[self.col("_filled")]
 
     def _get_memory(self, iter):
@@ -1127,16 +1075,6 @@
 
         return hbox
 
-    def set_bank_list(self, banks):
-        self.choices[_("Bank")].clear()
-        self.choices[_("Bank")].append(("", "(None)"))
-
-        i = ord("A")
-        for bank in banks:
-            self.choices[_("Bank")].append((str(bank),
-                                            ("%s-%s" % (chr(i), str(bank)))))
-            i += 1
-        
     def set_show_special(self, show):
         self.show_special = show
         self.prefill()
@@ -1166,8 +1104,6 @@
 
     def get_unsupported_columns(self):
         maybe_hide = [
-            ("has_bank_index", _("Bank Index")),
-            ("has_bank", _("Bank")),
             ("has_dtcs", _("DTCS Code")),
             ("has_dtcs_polarity", _("DTCS Pol")),
             ("has_mode", _("Mode")),
@@ -1240,7 +1176,6 @@
 
         (min, max) = self._features.memory_bounds
 
-        self.choices[_("Bank")] = gtk.ListStore(TYPE_STRING, TYPE_STRING)
         self.choices[_("Mode")] = self._features["valid_modes"]
         self.choices[_("Tone Mode")] = self._features["valid_tmodes"]
         self.choices[_("Cross Mode")] = self._features["valid_cross_modes"]
@@ -1251,10 +1186,6 @@
         if self._features["valid_power_levels"]:
             self.defaults[_("Power")] = self._features["valid_power_levels"][0]
 
-        job = common.RadioJob(self.set_bank_list, "get_banks")
-        job.set_desc(_("Getting bank list"))
-        rthread.submit(job)
-
         if not self._features["can_odd_split"]:
             # We need a new list, so .remove() won't work for us
             self.choices[_("Duplex")] = [x for x in self.choices[_("Duplex")]
@@ -1362,9 +1293,6 @@
                     continue
 
             mem.name = self.rthread.radio.filter_name(mem.name)
-            if not self._features.has_bank:
-                mem.bank = None
-                mem.bank_index = -1
 
             src_number = mem.number
             mem.number = loc



More information about the chirp_devel mailing list