Exemplo n.º 1
0
    def _edited(self, rend, path, new, col):
        iter = self.__store.get_iter(path)

        if col == self.col_nloc:
            nloc, = self.__store.get(iter, self.col_nloc)

            try:
                val = int(new)
            except ValueError:
                common.show_error(_("Invalid value. Must be an integer."))
                return

            if val == nloc:
                return

            if self._check_for_dupe(val):
                d = gtk.MessageDialog(parent=self, buttons=gtk.BUTTONS_OK)
                d.set_property(
                    "text",
                    _("Location {number} is already being "
                      "imported").format(number=val))
                d.run()
                d.destroy()
                return

            self.record_use_of(val)

        elif col == self.col_name or col == self.col_comm:
            val = str(new)

        else:
            return

        self.__store.set(iter, col, val)
Exemplo n.º 2
0
    def run(self):
        r = gtk.Dialog.run(self)
        if r != gtk.RESPONSE_OK:
            return None

        vendor = self.__vend.get_active_text()
        model = self.__modl.get_active_text()

        cs = CloneSettings()
        cs.port = self.__port.get_active_text()
        if model == _("Detect"):
            try:
                cs.radio_class = detect.DETECT_FUNCTIONS[vendor](cs.port)
                if not cs.radio_class:
                    raise Exception(
                        _("Unable to detect radio on {port}").format(
                            port=cs.port))
            except Exception as e:
                d = inputdialog.ExceptionDialog(e)
                d.run()
                d.destroy()
                return None
        else:
            for rclass in directory.DRV_TO_RADIO.values():
                if rclass.MODEL == model:
                    cs.radio_class = rclass
                    break
                alias_match = None
                for alias in rclass.ALIASES:
                    if alias.MODEL == model:
                        alias_match = rclass
                        alias_class = alias
                        break
                if alias_match:

                    class DynamicRadioAlias(rclass):
                        VENDOR = alias.VENDOR
                        MODEL = alias.MODEL
                        VARIANT = alias.VARIANT

                    cs.radio_class = DynamicRadioAlias
                    LOG.debug(
                        'Chose %s alias for %s because model %s selected' %
                        (alias_match, cs.radio_class, model))
                    break
            if not cs.radio_class:
                common.show_error(
                    _("Internal error: Unable to upload to {model}").format(
                        model=model))
                LOG.info(self.__vendors)
                return None

        conf = config.get("state")
        conf.set("last_port", cs.port)
        conf.set("last_vendor", cs.radio_class.VENDOR)
        conf.set("last_model", model)

        return cs
Exemplo n.º 3
0
    def do_import(self, filen):
        current_editor = self.get_current_editor()
        if not isinstance(current_editor, memedit.MemoryEditor):
            # FIXME: We need a nice message to let the user know that they
            # need to select the appropriate memory editor tab before doing
            # and import so that we know which thread and editor to import
            # into and refresh. This will do for the moment.
            common.show_error("Memory editor must be selected before import")
        try:
            src_radio = directory.get_radio_by_image(filen)
        except Exception as e:
            common.show_error(e)
            return

        if isinstance(src_radio, chirp_common.NetworkSourceRadio):
            ww = importdialog.WaitWindow("Querying...", self.parent_window)
            ww.show()

            def status(status):
                ww.set(float(status.cur) / float(status.max))

            try:
                src_radio.status_fn = status
                src_radio.do_fetch()
            except Exception as e:
                common.show_error(e)
                ww.hide()
                return
            ww.hide()

        try:
            if src_radio.get_features().has_sub_devices:
                src_radio = self.choose_sub_device(src_radio)
        except Exception as e:
            common.show_error(e)
            return

        if len(src_radio.errors) > 0:
            _filen = os.path.basename(filen)
            common.show_error_text(
                _("There were errors while opening {file}. "
                  "The affected memories will not "
                  "be importable!").format(file=_filen),
                "\r\n".join(src_radio.errors))

        try:
            count = self._do_import_locked(importdialog.ImportDialog,
                                           src_radio, self.rthread)
            reporting.report_model_usage(src_radio, "importsrc", True)
        except Exception as e:
            common.log_exception()
            common.show_error(
                _("There was an error during "
                  "import: {error}").format(error=e))
Exemplo n.º 4
0
 def do_export(self, filen):
     try:
         if filen.lower().endswith(".csv"):
             dst_radio = generic_csv.CSVRadio(filen)
         elif filen.lower().endswith(".chirp"):
             dst_radio = generic_xml.XMLRadio(filen)
         else:
             raise Exception(_("Unsupported file type"))
     except Exception, e:
         common.log_exception()
         common.show_error(e)
         return
Exemplo n.º 5
0
 def do_export(self, filen):
     try:
         if filen.lower().endswith(".csv"):
             dst_radio = generic_csv.CSVRadio(filen)
         elif filen.lower().endswith(".chirp"):
             dst_radio = generic_xml.XMLRadio(filen)
         else:
             raise Exception(_("Unsupported file type"))
     except Exception, e:
         common.log_exception()
         common.show_error(e)
         return
Exemplo n.º 6
0
 def do_import(self, filen):
     current_editor = self.get_current_editor()
     if not isinstance(current_editor, memedit.MemoryEditor):
         # FIXME: We need a nice message to let the user know that they
         # need to select the appropriate memory editor tab before doing
         # and import so that we know which thread and editor to import
         # into and refresh. This will do for the moment.
         common.show_error("Memory editor must be selected before import")
     try:
         src_radio = directory.get_radio_by_image(filen)
     except Exception, e:
         common.show_error(e)
         return
Exemplo n.º 7
0
 def do_import(self, filen):
     current_editor = self.get_current_editor()
     if not isinstance(current_editor, memedit.MemoryEditor):
         # FIXME: We need a nice message to let the user know that they
         # need to select the appropriate memory editor tab before doing
         # and import so that we know which thread and editor to import
         # into and refresh. This will do for the moment.
         common.show_error("Memory editor must be selected before import")
     try:
         src_radio = directory.get_radio_by_image(filen)
     except Exception, e:
         common.show_error(e)
         return
Exemplo n.º 8
0
        def do_mapping_index(result, memory):
            if isinstance(result, Exception):
                common.show_error("Failed to add {mem} to mapping: {err}"
                                  .format(mem=memory.number,
                                          err=str(result)),
                                  parent=self.editorset.parent_window)
                return
            self.emit("changed")
            # Step 3: Set the memory's mapping index (maybe)
            if not is_indexed or index is None:
                return do_refresh_memory()

            job = common.RadioJob(do_refresh_memory,
                                  "set_memory_index", memory, mapping, index)
            job.set_target(self._model)
            job.set_desc(_("Updating {type} index "
                           "for memory {num}").format(type=self._type,
                                                      num=memory.number))
            self.rthread.submit(job)
Exemplo n.º 9
0
    def do_import(self, dst_rthread):
        i = 0
        error_messages = {}
        import_list = self.get_import_list()

        src_features = self.src_radio.get_features()

        for old, new, name, comm in import_list:
            i += 1
            LOG.debug("%sing %i -> %i" % (self.ACTION, old, new))

            src = self.src_radio.get_memory(old)

            try:
                mem = import_logic.import_mem(self.dst_radio, src_features,
                                              src, {
                                                  "number": new,
                                                  "name": name,
                                                  "comment": comm
                                              })
            except import_logic.ImportError as e:
                LOG.error("Import error: %s", e)
                error_messages[new] = str(e)
                continue

            job = common.RadioJob(None, "set_memory", mem)
            desc = _("Setting memory {number}").format(number=mem.number)
            job.set_desc(desc)
            dst_rthread._qsubmit(job, 0)

            job = ImportMemoryBankJob(None, mem, self.src_radio, src)
            job.set_desc(_("Importing bank information"))
            dst_rthread._qsubmit(job, 0)

        if error_messages.keys():
            msg = _("Error importing memories:") + "\r\n"
            for num, msgs in error_messages.items():
                msg += "%s: %s" % (num, ",".join(msgs))
            common.show_error(msg)

        return i
Exemplo n.º 10
0
    def do_export(self, filen):
        try:
            if filen.lower().endswith(".csv"):
                dst_radio = generic_csv.CSVRadio(filen)
            elif filen.lower().endswith(".chirp"):
                dst_radio = generic_xml.XMLRadio(filen)
            else:
                raise Exception(_("Unsupported file type"))
        except Exception as e:
            common.log_exception()
            common.show_error(e)
            return

        dst_rthread = common.RadioThread(dst_radio)
        dst_rthread.setDaemon(True)
        dst_rthread.start()

        try:
            count = self._do_import_locked(importdialog.ExportDialog,
                                           self.rthread.radio,
                                           dst_rthread)
        except Exception as e:
            common.log_exception()
            common.show_error(_("There was an error during "
                                "export: {error}").format(error=e),
                              self.parent_window)
            return

        if count <= 0:
            return

        # Wait for thread queue to complete
        dst_rthread._qlock_when_idle()

        try:
            dst_radio.save(filename=filen)
        except Exception as e:
            common.log_exception()
            common.show_error(_("There was an error during "
                                "export: {error}").format(error=e),
                              self)
Exemplo n.º 11
0
 def _save_setting(self, widget, value):
     try:
         self._do_save_setting(widget, value)
     except settings.InvalidValueError, e:
         common.show_error(_("Invalid setting value: %s") % e)
Exemplo n.º 12
0
                        break
                if alias_match:

                    class DynamicRadioAlias(rclass):
                        VENDOR = alias.VENDOR
                        MODEL = alias.MODEL
                        VARIANT = alias.VARIANT

                    cs.radio_class = DynamicRadioAlias
                    LOG.debug(
                        'Chose %s alias for %s because model %s selected' %
                        (alias_match, cs.radio_class, model))
                    break
            if not cs.radio_class:
                common.show_error(
                    _("Internal error: Unable to upload to {model}").format(
                        model=model))
                LOG.info(self.__vendors)
                return None

        conf = config.get("state")
        conf.set("last_port", cs.port)
        conf.set("last_vendor", cs.radio_class.VENDOR)
        conf.set("last_model", model)

        return cs


class CloneCancelledException(Exception):
    pass
Exemplo n.º 13
0
class EditorSet(gtk.VBox):
    __gsignals__ = {
        "want-close": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        "status":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
        "usermsg":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
        "editor-selected":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
    }

    def _make_device_mapping_editors(self, device, devrthread, index):
        sub_index = 0
        memory_editor = self.editors["memedit%i" % index]
        mappings = device.get_mapping_models()
        for mapping_model in mappings:
            members = bankedit.MappingMembershipEditor(devrthread, self,
                                                       mapping_model)
            label = mapping_model.get_name()
            if self.rf.has_sub_devices:
                label += "(%s)" % device.VARIANT
            lab = gtk.Label(label)
            self.tabs.append_page(members.root, lab)
            self.editors["mapping_members%i%i" % (index, sub_index)] = members

            basename = common.unpluralize(mapping_model.get_name())
            names = bankedit.MappingNameEditor(devrthread, mapping_model)
            label = "%s Names" % basename
            if self.rf.has_sub_devices:
                label += " (%s)" % device.VARIANT
            lab = gtk.Label(label)
            self.tabs.append_page(names.root, lab)
            self.editors["mapping_names%i%i" % (index, sub_index)] = names

            members.root.show()
            members.connect("changed", self.editor_changed)
            if hasattr(mapping_model.get_mappings()[0], "set_name"):
                names.root.show()
                members.connect("changed", lambda x: names.mappings_changed())
                names.connect("changed", lambda x: members.mappings_changed())
                names.connect("changed", self.editor_changed)
            sub_index += 1

    def _make_device_editors(self, device, devrthread, index):
        if isinstance(device, chirp_common.IcomDstarSupport):
            memories = memedit.DstarMemoryEditor(devrthread)
        else:
            memories = memedit.MemoryEditor(devrthread)

        memories.connect("usermsg", lambda e, m: self.emit("usermsg", m))
        memories.connect("changed", self.editor_changed)

        if self.rf.has_sub_devices:
            label = (_("Memories (%(variant)s)") %
                     dict(variant=device.VARIANT))
            rf = device.get_features()
        else:
            label = _("Memories")
            rf = self.rf
        lab = gtk.Label(label)
        self.tabs.append_page(memories.root, lab)
        memories.root.show()
        self.editors["memedit%i" % index] = memories

        self._make_device_mapping_editors(device, devrthread, index)

        if isinstance(device, chirp_common.IcomDstarSupport):
            editor = dstaredit.DStarEditor(devrthread)
            self.tabs.append_page(editor.root, gtk.Label(_("D-STAR")))
            editor.root.show()
            editor.connect("changed", self.dstar_changed, memories)
            editor.connect("changed", self.editor_changed)
            self.editors["dstar"] = editor

    def __init__(self,
                 source,
                 parent_window=None,
                 filename=None,
                 tempname=None):
        gtk.VBox.__init__(self, True, 0)

        self.parent_window = parent_window

        if isinstance(source, str):
            self.filename = source
            self.radio = directory.get_radio_by_image(self.filename)
        elif isinstance(source, chirp_common.Radio):
            self.radio = source
            self.filename = filename or tempname or source.VARIANT
        else:
            raise Exception("Unknown source type")

        rthread = common.RadioThread(self.radio)
        rthread.setDaemon(True)
        rthread.start()

        rthread.connect("status", lambda e, m: self.emit("status", m))

        self.tabs = gtk.Notebook()
        self.tabs.connect("switch-page", self.tab_selected)
        self.tabs.set_tab_pos(gtk.POS_LEFT)

        self.editors = {}

        self.rf = self.radio.get_features()
        if self.rf.has_sub_devices:
            devices = self.radio.get_sub_devices()
        else:
            devices = [self.radio]

        index = 0
        for device in devices:
            devrthread = common.RadioThread(device, rthread)
            devrthread.setDaemon(True)
            devrthread.start()
            self._make_device_editors(device, devrthread, index)
            index += 1

        if self.rf.has_settings:
            editor = settingsedit.SettingsEditor(rthread)
            self.tabs.append_page(editor.root, gtk.Label(_("Settings")))
            editor.root.show()
            editor.connect("changed", self.editor_changed)
            self.editors["settings"] = editor

        conf = config.get()
        if (hasattr(self.rthread.radio, '_memobj')
                and conf.get_bool("developer", "state")):
            editor = radiobrowser.RadioBrowser(self.rthread)
            lab = gtk.Label(_("Browser"))
            self.tabs.append_page(editor.root, lab)
            editor.connect("changed", self.editor_changed)
            self.editors["browser"] = editor

        self.pack_start(self.tabs)
        self.tabs.show()

        self.label = self.text_label = None
        self.make_label()
        self.modified = (tempname is not None)
        if tempname:
            self.filename = tempname
        self.update_tab()

    def make_label(self):
        self.label = gtk.HBox(False, 0)

        self.text_label = gtk.Label("")
        self.text_label.show()
        self.label.pack_start(self.text_label, 1, 1, 1)

        button = gtk.Button()
        button.set_relief(gtk.RELIEF_NONE)
        button.set_focus_on_click(False)

        icon = gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
        icon.show()
        button.add(icon)

        button.connect("clicked", lambda x: self.emit("want-close"))
        button.show()
        self.label.pack_start(button, 0, 0, 0)

        self.label.show()

    def update_tab(self):
        fn = os.path.basename(self.filename)
        if self.modified:
            text = "%s*" % fn
        else:
            text = fn

        self.text_label.set_text(self.radio.get_name() + ": " + text)

    def save(self, fname=None):
        if not fname:
            fname = self.filename
            if not os.path.exists(self.filename):
                return  # Probably before the first "Save as"
        else:
            self.filename = fname

        self.rthread.lock()
        try:
            self.radio.save(fname)
        except:
            self.rthread.unlock()
            raise
        self.rthread.unlock()

        self.modified = False
        self.update_tab()

    def dstar_changed(self, dstared, memedit):
        memedit.set_urcall_list(dstared.editor_ucall.get_callsigns())
        memedit.set_repeater_list(dstared.editor_rcall.get_callsigns())
        memedit.prefill()

    def editor_changed(self, target_editor=None):
        LOG.debug("%s changed" % target_editor)
        if not isinstance(self.radio, chirp_common.LiveRadio):
            self.modified = True
            self.update_tab()
        for editor in self.editors.values():
            if editor != target_editor:
                editor.other_editor_changed(target_editor)

    def get_tab_label(self):
        return self.label

    def is_modified(self):
        return self.modified

    def _do_import_locked(self, dlgclass, src_radio, dst_rthread):

        # An import/export action needs to be done in the absence of any
        # other queued changes.  So, we make sure that nothing else is
        # staged for the thread and lock it up.  Then we use the hidden
        # interface to queue our own changes before opening it up to the
        # rest of the world.

        dst_rthread._qlock_when_idle(5)  # Suspend job submission when idle

        dialog = dlgclass(src_radio, dst_rthread.radio, self.parent_window)
        r = dialog.run()
        dialog.hide()
        if r != gtk.RESPONSE_OK:
            dst_rthread._qunlock()
            return

        count = dialog.do_import(dst_rthread)
        LOG.debug("Imported %i" % count)
        dst_rthread._qunlock()

        if count > 0:
            self.editor_changed()
            current_editor = self.get_current_editor()
            gobject.idle_add(current_editor.prefill)

        return count

    def choose_sub_device(self, radio):
        devices = radio.get_sub_devices()
        choices = [x.VARIANT for x in devices]

        d = inputdialog.ChoiceDialog(choices)
        text = _("The {vendor} {model} has multiple independent sub-devices")
        d.label.set_text(
            text.format(vendor=radio.VENDOR, model=radio.MODEL) + os.linesep +
            _("Choose one to import from:"))
        r = d.run()
        chosen = d.choice.get_active_text()
        d.destroy()
        if r == gtk.RESPONSE_CANCEL:
            raise Exception(_("Cancelled"))
        for d in devices:
            if d.VARIANT == chosen:
                return d

        raise Exception(_("Internal Error"))

    def do_import(self, filen):
        current_editor = self.get_current_editor()
        if not isinstance(current_editor, memedit.MemoryEditor):
            # FIXME: We need a nice message to let the user know that they
            # need to select the appropriate memory editor tab before doing
            # and import so that we know which thread and editor to import
            # into and refresh. This will do for the moment.
            common.show_error("Memory editor must be selected before import")
        try:
            src_radio = directory.get_radio_by_image(filen)
        except Exception, e:
            common.show_error(e)
            return

        if isinstance(src_radio, chirp_common.NetworkSourceRadio):
            ww = importdialog.WaitWindow("Querying...", self.parent_window)
            ww.show()

            def status(status):
                ww.set(float(status.cur) / float(status.max))

            try:
                src_radio.status_fn = status
                src_radio.do_fetch()
            except Exception, e:
                common.show_error(e)
                ww.hide()
                return
            ww.hide()
Exemplo n.º 14
0
 def setting_cb(result):
     if isinstance(result, Exception):
         common.show_error(_("Error in setting value: %s") % result)
     elif self._changed:
         self.emit("changed")
         self._changed = False
Exemplo n.º 15
0
                ww.set(float(status.cur) / float(status.max))

            try:
                src_radio.status_fn = status
                src_radio.do_fetch()
            except Exception, e:
                common.show_error(e)
                ww.hide()
                return
            ww.hide()

        try:
            if src_radio.get_features().has_sub_devices:
                src_radio = self.choose_sub_device(src_radio)
        except Exception, e:
            common.show_error(e)
            return

        if len(src_radio.errors) > 0:
            _filen = os.path.basename(filen)
            common.show_error_text(
                _("There were errors while opening {file}. "
                  "The affected memories will not "
                  "be importable!").format(file=_filen),
                "\r\n".join(src_radio.errors))

        try:
            count = self._do_import_locked(importdialog.ImportDialog,
                                           src_radio, self.rthread)
            reporting.report_model_usage(src_radio, "importsrc", True)
        except Exception, e:
Exemplo n.º 16
0
 def _save_setting(self, widget, value):
     try:
         self._do_save_setting(widget, value)
     except settings.InvalidValueError as e:
         common.show_error(_("Invalid setting value: %s") % e)
Exemplo n.º 17
0
 def setting_cb(result):
     if isinstance(result, Exception):
         common.show_error(_("Error in setting value: %s") % result)
     elif self._changed:
         self.emit("changed")
         self._changed = False
Exemplo n.º 18
0
                ww.set(float(status.cur) / float(status.max))

            try:
                src_radio.status_fn = status
                src_radio.do_fetch()
            except Exception, e:
                common.show_error(e)
                ww.hide()
                return
            ww.hide()

        try:
            if src_radio.get_features().has_sub_devices:
                src_radio = self.choose_sub_device(src_radio)
        except Exception, e:
            common.show_error(e)
            return

        if len(src_radio.errors) > 0:
            _filen = os.path.basename(filen)
            common.show_error_text(_("There were errors while opening {file}. "
                                     "The affected memories will not "
                                     "be importable!").format(file=_filen),
                                   "\r\n".join(src_radio.errors))

        try:
            count = self._do_import_locked(importdialog.ImportDialog,
                                           src_radio,
                                           self.rthread)
            reporting.report_model_usage(src_radio, "importsrc", True)
        except Exception, e:
Exemplo n.º 19
0
                    cs.radio_class = rclass
                    break
                alias_match = None
                for alias in rclass.ALIASES:
                    if alias.MODEL == model:
                        alias_match = rclass
                        break
                if alias_match:
                    cs.radio_class = rclass
                    LOG.debug(
                        'Chose %s alias for %s because model %s selected' % (
                            alias_match, cs.radio_class, model))
                    break
            if not cs.radio_class:
                common.show_error(
                    _("Internal error: Unable to upload to {model}").format(
                        model=model))
                LOG.info(self.__vendors)
                return None

        conf = config.get("state")
        conf.set("last_port", cs.port)
        conf.set("last_vendor", cs.radio_class.VENDOR)
        conf.set("last_model", model)

        return cs


class CloneCancelledException(Exception):
    pass