Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow bank model with special memories #1160

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions chirp/chirp_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,19 @@ def get_next_mapping_index(self, mapping):
raise NotImplementedError()


class SpecialBankModelInterface:
"""Interface for bank models that include special channels.

If this is mixed into a BankModel, then any special channels returned by
get_bankable_specials() are candidates for parameters where a Memory is
used.
"""

def get_bankable_specials(self):
"""Return a list of special names that can be put into banks."""
return []


class MTOBankModel(BankModel):
"""A bank model where one memory can be in multiple banks at once """
pass
Expand Down
73 changes: 73 additions & 0 deletions chirp/drivers/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,81 @@ def get_radio(self):
self.rclass = baofeng_uv17Pro.UV17Pro


class FakeBankModel(chirp_common.BankModel,
chirp_common.SpecialBankModelInterface):
def __init__(self, radio, name='Banks'):
super().__init__(radio, name)
self._banks = {i: set() for i in range(5)}

def get_bankable_specials(self):
return self._radio.get_features().valid_special_chans[:-1]

def get_num_mappings(self):
return len(self._banks)

def get_mappings(self):
return [chirp_common.Bank(self, i, 'Bank %i' % i) for i in range(5)]

def get_memory_mappings(self, memory):
banks = self.get_mappings()
in_banks = [i for i in range(5) if memory.number in self._banks[i]]
return [bank for bank in banks if bank.get_index() in in_banks]

def add_memory_to_mapping(self, memory, mapping):
self._banks[mapping.get_index()].add(memory.number)

def remove_memory_from_mapping(self, memory, mapping):
self._banks[mapping.get_index()].remove(memory.number)


class FakeClone(chirp_common.CloneModeRadio):
VENDOR = 'CHIRP'
MODEL = 'Fake Clone'

def __init__(self, pipe):
super().__init__(pipe)
self._memories = [chirp_common.Memory(i) for i in range(10)]
# Make sure these are not contiguous with main memory so that there
# are no edge cases
self._specials = [chirp_common.Memory(100 + i) for i in range(3)]
for i, mem in enumerate(self._memories + self._specials):
mem.freq = 146000000 + (i * 100000)
mem.empty = i < 5
if mem in self._specials:
mem.extd_number = 'Special %i' % mem.number
self._special_names = [x.extd_number for x in self._specials]

def get_features(self) -> chirp_common.RadioFeatures:
rf = chirp_common.RadioFeatures()
rf.valid_special_chans = self._special_names
rf.valid_bands = [(144000000, 148000000)]
rf.memory_bounds = (0, 9)
rf.has_bank = True
return rf

def get_bank_model(self):
return FakeBankModel(self)

def get_memory(self, number):
if isinstance(number, str):
return self._specials[self._special_names.index(number)]
else:
try:
return self._memories[number]
except IndexError:
return self._specials[number - 100]

def set_memory(self, memory):
if memory.extd_number:
self._specials[self._special_names.index(memory.extd_number)] = (
memory)
else:
self._memories[memory.number] = memory


def register_fakes():
directory.register(FakeLiveRadio)
directory.register(FakeLiveSlowRadio)
directory.register(FakeLiveRadioWithErrors)
directory.register(FakeCloneFail)
directory.register(FakeClone)
56 changes: 41 additions & 15 deletions chirp/wxui/bankedit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# 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 logging
import platform

import wx
Expand All @@ -24,6 +25,7 @@
from chirp.wxui import memedit

CONF = config.get()
LOG = logging.getLogger(__name__)


if platform.system() == 'Linux':
Expand Down Expand Up @@ -73,13 +75,17 @@ def __init__(self, radio, *a, **k):
self._radio = radio
self._features = radio.get_features()
self._bankmodel = radio.get_bank_model()
if isinstance(self._bankmodel, chirp_common.SpecialBankModelInterface):
self._specials = self._bankmodel.get_bankable_specials()
else:
self._specials = []

self._col_defs = self._setup_columns()

self._grid = memedit.ChirpMemoryGrid(self)
self._grid.CreateGrid(
self._features.memory_bounds[1] - self._features.memory_bounds[0] +
1, len(self._col_defs))
1 + len(self._specials), len(self._col_defs))
# GridSelectNone only available in >=4.2.0
if hasattr(wx.grid.Grid, 'GridSelectNone'):
self._grid.SetSelectionMode(wx.grid.Grid.GridSelectNone)
Expand Down Expand Up @@ -143,6 +149,10 @@ def refresh_memories(self):
mem = self._radio.get_memory(i)
self._refresh_memory(mem)

for special in self._specials:
mem = self._radio.get_memory(special)
self._refresh_memory(mem)

wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=True)

def _setup_columns(self):
Expand Down Expand Up @@ -174,10 +184,23 @@ def bank2col(self, bank):
return bank + self._meta_cols

def row2mem(self, row):
return row + self._features.memory_bounds[0]
number = row + self._features.memory_bounds[0]
try:
return self._memory_cache[number]
except KeyError:
special = self._specials[row -
self._features.memory_bounds[1] -
self._features.memory_bounds[0] - 1]
return self._memory_cache[special]

def mem2row(self, mem):
return mem - self._features.memory_bounds[0]
if mem.extd_number:
row = (self._features.memory_bounds[1] -
self._features.memory_bounds[0] +
self._specials.index(mem.extd_number) + 1)
return row
else:
return mem.number - self._features.memory_bounds[0]

def _colheader_mouseover(self, event):
x = event.GetX()
Expand Down Expand Up @@ -223,16 +246,16 @@ def _index_changed(self, event):
if isinstance(self._col_defs[col], ChirpBankIndexColumn):
self._change_memory_index(self.row2mem(row), int(value))

def _change_memory_index(self, number, index):
def _change_memory_index(self, mem, index):
for i, bank_index in enumerate(self._bank_index_order):
if self._grid.GetCellValue(self.mem2row(number),
if self._grid.GetCellValue(self.mem2row(mem),
self.bank2col(i)) == BANK_SET_VALUE:
member_bank = self._bank_indexes[bank_index]
break
else:
raise Exception(_('Memory must be in a bank to be edited'))

self._bankmodel.set_memory_index(self._memory_cache[number],
self._bankmodel.set_memory_index(self._memory_cache[mem.number],
member_bank,
index)

Expand All @@ -253,8 +276,7 @@ def _memory_changed(self, event):
self.col2bank(col),
value != BANK_SET_VALUE)

def _change_memory_mapping(self, number, bank, present):
mem = self._memory_cache[number]
def _change_memory_mapping(self, mem, bank, present):
bank = self._bank_indexes[self._bank_index_order[bank]]
if present:
self._bankmodel.add_memory_to_mapping(mem, bank)
Expand All @@ -267,16 +289,20 @@ def _change_memory_mapping(self, number, bank, present):

@common.error_proof()
def _refresh_memory(self, mem):
self._memory_cache[mem.number] = mem
self._grid.SetRowLabelValue(self.mem2row(mem.number),
'%i' % mem.number)
self._memory_cache[mem.extd_number or mem.number] = mem
self._grid.SetRowLabelValue(self.mem2row(mem),
mem.extd_number or ('%i' % mem.number))
if mem.empty:
self._grid.HideRow(self.mem2row(mem))
else:
self._grid.ShowRow(self.mem2row(mem))

bank_index = None
member = [bank.get_index()
for bank in self._bankmodel.get_memory_mappings(mem)]
for i, bank in enumerate(self._bank_indexes.values()):
present = bank.get_index() in member and not mem.empty
self._grid.SetCellValue(self.mem2row(mem.number),
self._grid.SetCellValue(self.mem2row(mem),
self.bank2col(i),
present and BANK_SET_VALUE or '')
if present and isinstance(self._bankmodel,
Expand All @@ -290,14 +316,14 @@ def _refresh_memory(self, mem):
if meta_col.name == 'freq':
freq = '' if mem.empty else chirp_common.format_freq(mem.freq)
self._grid.SetCellValue(
self.mem2row(mem.number), i, freq)
self.mem2row(mem), i, freq)
elif meta_col.name == 'name':
self._grid.SetCellValue(
self.mem2row(mem.number),
self.mem2row(mem),
i, '' if mem.empty else mem.name)
elif meta_col.name == 'bank_index' and bank_index is not None:
self._grid.SetCellValue(
self.mem2row(mem.number),
self.mem2row(mem),
i, '' if mem.empty else '%i' % bank_index)


Expand Down
Loading