[chirp_devel] [PATCH 2 of 2] Add memory detail editor
Dan Smith
Mon May 7 17:22:05 PDT 2012
# HG changeset patch
# User Dan Smith <dsmith at danplanet.com>
# Date 1336436519 25200
# Node ID 06d821868172fdd77282ebef4c785d050be09360
# Parent d059f6451dc6c0e6c173b624cb8616e7e28c74c7
Add memory detail editor
This adds an "Edit" option to the right-click context menu for a memory,
which opens a dialog window allowing somewhat easier atomic editing of a
memory's values. I think this will provide an easier way to expose some
more complicated and radio-specific features of the memory objects,
such as split tones and perhaps even D-STAR attributes.
#00
diff -r d059f6451dc6 -r 06d821868172 chirpui/memdetail.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/chirpui/memdetail.py Mon May 07 17:21:59 2012 -0700
@@ -0,0 +1,175 @@
+# Copyright 2012 Dan Smith <dsmith at 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
+
+from chirp import chirp_common
+from chirpui import miscwidgets
+
+POL = ["NN", "NR", "RN", "RR"]
+
+class ValueEditor:
+ """Base class"""
+ def __init__(self, features, memory, errfn, name, data=None):
+ self._features = features
+ self._memory = memory
+ self._errfn = errfn
+ self._name = name
+ self._widget = None
+ self._init(data)
+
+ def _init(self, data):
+ """Type-specific initialization"""
+
+ def get_widget(self):
+ """Returns the widget associated with this editor"""
+ return self._widget
+
+ def _mem_value(self):
+ """Returns the raw value from the memory associated with this name"""
+ return getattr(self._memory, self._name)
+
+ def _get_value(self):
+ """Returns the value from the widget that should be set in the memory"""
+
+ def update(self):
+ """Updates the memory object with self._getvalue()"""
+
+ try:
+ setattr(self._memory, self._name, self._get_value())
+ except ValueError, e:
+ self._errfn(self._name, str(e))
+ return str(e)
+ print self._memory
+
+ # Validate!
+
+ self._errfn(self._name, None)
+
+class StringEditor(ValueEditor):
+ def _init(self, data):
+ self._widget = gtk.Entry(int(data))
+ self._widget.set_text(str(self._mem_value()))
+ self._widget.connect("changed", self.changed)
+
+ def _get_value(self):
+ return self._widget.get_text()
+
+ def changed(self, _widget):
+ self.update()
+
+class ChoiceEditor(ValueEditor):
+ def _init(self, data):
+ self._widget = miscwidgets.make_choice([str(x) for x in data],
+ False,
+ str(self._mem_value()))
+ self._widget.connect("changed", self.changed)
+
+ def _get_value(self):
+ return self._widget.get_active_text()
+
+ def changed(self, _widget):
+ self.update()
+
+class FloatChoiceEditor(ChoiceEditor):
+ def _get_value(self):
+ return float(self._widget.get_active_text())
+
+class FreqEditor(StringEditor):
+ def _init(self, data):
+ StringEditor._init(self, 0)
+ self._widget.set_text(chirp_common.format_freq(self._mem_value()))
+
+ def _get_value(self):
+ return chirp_common.parse_freq(self._widget.get_text())
+
+class OffsetEditor(FreqEditor):
+ pass
+
+class MemoryDetailEditor(gtk.Dialog):
+ """Detail editor for a memory"""
+
+ def _make_ui(self):
+ tab = gtk.Table(len(self._order), 3, False)
+ self.vbox.pack_start(tab, 1, 1, 1)
+ tab.show()
+
+ row = 0
+
+ def err(name, msg):
+ _img = self._editors[name][1]
+ if msg is None:
+ _img.clear()
+ else:
+ _img.set_from_stock(gtk.STOCK_NO, gtk.ICON_SIZE_MENU)
+
+ for name in self._order:
+ labeltxt, editorcls, data = self._elements[name]
+
+ label = gtk.Label(labeltxt)
+ img = gtk.Image()
+
+ editor = editorcls(self._features, self._memory,
+ err, name, data)
+
+ label.show()
+ tab.attach(label, 0, 1, row, row+1)
+
+ img.set_size_request(15, -1)
+ img.show()
+ tab.attach(img, 2, 3, row, row+1)
+
+ editor.get_widget().show()
+ tab.attach(editor.get_widget(), 1, 2, row, row+1)
+
+ self._editors[name] = editor, img
+ row += 1
+
+ def __init__(self, features, memory, parent=None):
+ gtk.Dialog.__init__(self,
+ title=_("Edit Memory #{num}").format(num=memory.number),
+ parent=parent,
+ buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
+ gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+ self._features = features
+ self._memory = memory
+
+ self._editors = {}
+ self._elements = {
+ "freq" : (_("Frequency"), FreqEditor, None),
+ "name" : (_("Name"), StringEditor, features.valid_name_length),
+ "tmode" : (_("Tone Mode"), ChoiceEditor, features.valid_tmodes),
+ "rtone" : (_("Tone"), FloatChoiceEditor, chirp_common.TONES),
+ "ctone" : (_("ToneSql"), FloatChoiceEditor, chirp_common.TONES),
+ "dtcs" : (_("DTCS Code"), ChoiceEditor, chirp_common.DTCS_CODES),
+ "dtcs_polarity" : (_("DTCS Pol"), ChoiceEditor, POL),
+ "cross_mode" : (_("Cross mode"), ChoiceEditor, features.valid_cross_modes),
+ "duplex" : (_("Duplex"), ChoiceEditor, features.valid_duplexes),
+ "offset" : (_("Offset"), OffsetEditor, None),
+ "mode" : (_("Mode"), ChoiceEditor, features.valid_modes),
+ # Power
+ "tuning_step" : (_("Tune Step"), FloatChoiceEditor, features.valid_tuning_steps),
+ "skip" : (_("Skip"), ChoiceEditor, features.valid_skips),
+ "comment" : (_("Comment"), StringEditor, 256),
+ }
+ self._order = ["freq", "name", "tmode", "rtone", "ctone",
+ "dtcs", "dtcs_polarity", "duplex", "offset",
+ "mode", "tuning_step", "skip", "comment"]
+
+ self._make_ui()
+ self.set_default_size(400, -1)
+
+ def get_memory(self):
+ return self._memory
diff -r d059f6451dc6 -r 06d821868172 chirpui/memedit.py
--- a/chirpui/memedit.py Mon May 07 17:21:59 2012 -0700
+++ b/chirpui/memedit.py Mon May 07 17:21:59 2012 -0700
@@ -32,7 +32,7 @@
import pickle
import os
-from chirpui import common, shiftdialog, miscwidgets, config
+from chirpui import common, shiftdialog, miscwidgets, config, memdetail
from chirp import chirp_common, errors, directory, import_logic
def handle_toggle(_, path, store, col):
@@ -612,6 +612,18 @@
job.set_desc(_("Getting raw memory {number}").format(number=loc_b))
self.rthread.submit(job)
+ def edit_memory(self, memory):
+ dlg = memdetail.MemoryDetailEditor(self._features, memory)
+ r = dlg.run()
+ if r == gtk.RESPONSE_OK:
+ self.need_refresh = True
+ mem = dlg.get_memory()
+ job = common.RadioJob(self._set_memory_cb, "set_memory", mem)
+ job.set_desc(_("Writing memory {number}").format(number=mem.number))
+ self.rthread.submit(job)
+ self.emit("changed")
+ dlg.destroy()
+
def mh(self, _action, store, paths):
action = _action.get_name()
iter = store.get_iter(paths[0])
@@ -648,6 +660,9 @@
self._show_raw(cur_pos)
elif action == "devdiffraw":
self._diff_raw(paths)
+ elif action == "edit":
+ job = common.RadioJob(self.edit_memory, "get_memory", cur_pos)
+ self.rthread.submit(job)
if changed:
self.emit("changed")
@@ -671,7 +686,8 @@
menu_xml = """
<ui>
- <popup name="Menu">
+ <popup name="Menu">
+ <menuitem action="edit"/>
<menuitem action="insert_prev"/>
<menuitem action="insert_next"/>
<menuitem action="delete"/>
@@ -694,6 +710,7 @@
istwo = len(paths) == 2
actions = [
+ ("edit", _("Edit")),
("insert_prev", _("Insert row above")),
("insert_next", _("Insert row below")),
("delete", issingle and _("Delete") or _("Delete all")),
More information about the chirp_devel
mailing list