Esempio n. 1
0
class SelectInput(pyxbmct.AddonDialogWindow):
    def __init__(self, title=''):
        print 'Init Called'
        super(SelectInput, self).__init__(title)
        self.plugin = RequiredFeature('plugin').request()
        self.core = RequiredFeature('core').request()
        self.device_wrapper = RequiredFeature('device-wrapper').request()
        self.available_devices = self.device_wrapper.devices
        self.md5 = hashlib.md5()
        self.input_storage = self.plugin.get_storage('input_storage')

        for key, device in self.input_storage.iteritems():
            print 'Devices during INIT: %s' % device.name

        background = None
        if self.core.get_active_skin() == 'skin.osmc':
            media_path = '/usr/share/kodi/addons/skin.osmc/media'
            if os.path.exists(media_path):
                background = os.path.join(media_path, 'dialogs/DialogBackground_old.png')

        if background is not None:
            self.background.setImage(background)
            self.removeControl(self.title_background)
            self.removeControl(self.window_close_button)
            self.removeControl(self.title_bar)

        self.controls = {}
        self.add_ctrl_btn = None

        self.setGeometry(1280, 720, 12, 6, padding=60)
        self.place_add_ctrl_btn()
        self.setFocus(self.add_ctrl_btn)
        self.connect(pyxbmct.ACTION_NAV_BACK, self.close_and_save)
        self.init_existing_controls()  # initalise controls / mappings read from .storage

    def place_add_ctrl_btn(self):
        self.add_ctrl_btn = create_button()
        self.add_ctrl_btn.setLabel('Add Controller')
        self.placeControl(self.add_ctrl_btn, row=12, column=1, rowspan=1, columnspan=2)
        self.connect(self.add_ctrl_btn, self.add_ctrl)

    def add_ctrl(self, device=None):
        idx = len(self.controls)
        print 'Adding controler with index %s' % idx
        control = CtrlSelectionWrapper()
        self.md5.update(str(time.time()))
        ctrl_id = self.md5.hexdigest()
        control.id = ctrl_id
        control.idx = idx

        if not device:
            device = InputDevice()
            device.name = 'None (Disabled)'

        control.device = device

        label = create_label()
        label.setLabel('Controller ' + str(idx))
        control.label = label

        input_select_btn = create_button()
        input_select_btn.setLabel(
            control.device.name,
        )
        control.input_select_btn = input_select_btn

        trigger_adv_mapping_btn = create_button()
        trigger_adv_mapping_btn.setLabel('Add Mapping')
        control.trigger_adv_mapping_btn = trigger_adv_mapping_btn

        remove_btn = create_button()
        remove_btn.setLabel('Remove')
        control.remove_btn = remove_btn

        if idx == 0:
            row = 0
            adv_row = 1
        else:
            row = idx * 2
            adv_row = row + 1

        control.adv_row = adv_row

        self.placeControl(control.label, row=row, column=0, rowspan=1, columnspan=1)
        self.placeControl(control.input_select_btn, row=row, column=1, rowspan=1, columnspan=3)
        self.placeControl(control.trigger_adv_mapping_btn, row=row, column=4, rowspan=1, columnspan=1)
        self.placeControl(control.remove_btn, row=row, column=5, rowspan=1, columnspan=1)

        self.connect_controls(control)

        if control.device.is_kbd() or control.device.is_mouse() or control.device.is_none_device():
            trigger_adv_mapping_btn.setEnabled(False)
            # Still visible for now, but disabled
            # trigger_adv_mapping_btn.setVisible(False)

        control.set_internal_navigation()

        self.controls[control.id] = control

        # TODO: Should be a dedicated method (set_navigation)
        self.add_ctrl_btn.controlUp(control.input_select_btn)
        if control.adv_on_flag:
            control.adv_select_mapping.controlDown(self.add_ctrl_btn)
        else:
            control.input_select_btn.controlDown(self.add_ctrl_btn)
        previous_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx-1:
                previous_control = _control
        if previous_control:
            if previous_control.adv_on_flag:
                control.input_select_btn.controlUp(previous_control.adv_select_mapping)
                previous_control.adv_select_mapping.controlDown(control.input_select_btn)
            else:
                control.input_select_btn.controlUp(previous_control.input_select_btn)
                previous_control.input_select_btn.controlDown(control.input_select_btn)

        if control.device.mapping:
            self.trigger_advanced(control)

    def connect_controls(self, control):
        self.connect(control.input_select_btn, lambda: self.select_input(control))
        self.connect(control.remove_btn, lambda: self.remove_input(control))
        self.connect(control.trigger_adv_mapping_btn, lambda: self.trigger_advanced(control))

    def select_input(self, control):
        available_devices = self.filter_input_devices()
        device_names = [_dev.name for _dev in available_devices]
        controller = xbmcgui.Dialog().select('Select Input Device', device_names)
        if controller == -1:
            return
        else:
            print device_names[controller]
            device = self.device_wrapper.find_device_by_name(device_names[controller])
            control.device = device
            control.input_select_btn.setLabel(device.name)
            if device.is_kbd() or device.is_mouse() or device.is_none_device():
                control.trigger_adv_mapping_btn.setEnabled(False)
            else:
                control.trigger_adv_mapping_btn.setEnabled(True)
            self.input_storage[control.idx] = device

    def remove_input(self, control, dry=False):
        self.removeControls(control.controls_as_list())
        del_key = None
        for key, value in self.input_storage.iteritems():
            if value.name == control.device.name:
                del_key = key
        if not dry:
            del self.input_storage[del_key]
            del self.controls[control.id]
            del control
            self.init_existing_controls()
            self.setFocus(self.add_ctrl_btn)

    def trigger_advanced(self, control):
        control.adv_on(self)
        control.set_internal_navigation()
        next_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx+1:
                next_control = _control
        if next_control:
            control.adv_select_mapping.controlDown(next_control.input_select_btn)
            next_control.input_select_btn.controlUp(control.adv_select_mapping)
        else:
            control.adv_select_mapping.controlDown(self.add_ctrl_btn)
            self.add_ctrl_btn.controlUp(control.adv_select_mapping)
        self.setFocus(control.input_select_btn)

    def unset_advanced(self, control):
        control.adv_off(self)
        control.set_internal_navigation()
        control.unset_mapping_file()
        for key, device in self.input_storage.iteritems():
                if device.name == control.device.name:
                    device.mapping = None
                    print 'Found device and saved mapping'
                    break
        next_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx+1:
                next_control = _control
        if next_control:
            control.input_select_btn.controlDown(next_control.input_select_btn)
            next_control.input_select_btn.controlUp(control.input_select_btn)
        else:
            control.input_select_btn.controlDown(self.add_ctrl_btn)
            self.add_ctrl_btn.controlUp(control.input_select_btn)
        self.setFocus(control.input_select_btn)

    def select_mapping(self, control):
        browser = xbmcgui.Dialog().browse(1, 'Select Mapping File', 'files', '.map|.conf', False, False,
                                          os.path.expanduser('~'))
        if browser:
            control.set_mapping_file(browser)
            for key, device in self.input_storage.iteritems():
                print 'Iterating devices, current IS device: %s' % device.name
                if device.name == control.device.name:
                    device.mapping = browser
                    print 'Found device and saved mapping'
                    break

    def create_mapping(self, control):
        print 'Starting mapping'
        map_name = xbmcgui.Dialog().input(self.core.string('enter_filename'))

        progress_dialog = xbmcgui.DialogProgress()
        progress_dialog.create(
            self.core.string('name'),
            self.core.string('starting_mapping')
        )

        map_file = '%s/%s.map' % (os.path.expanduser('~'), map_name)

        moonlight_helper = RequiredFeature('moonlight-helper').request()
        success = moonlight_helper.create_ctrl_map_new(progress_dialog, map_file, control.device)

        if success:
            confirmed = xbmcgui.Dialog().yesno(
                    self.core.string('name'),
                    self.core.string('mapping_success'),
                    self.core.string('set_mapping_active')
            )

            self.core.logger.info('Dialog Yes No Value: %s' % confirmed)

            if confirmed:
                control.set_mapping_file(map_file)
                for key, device in self.input_storage.iteritems():
                    print 'Iterating devices, current IS device: %s' % device.name
                    if device.name == control.device.name:
                        device.mapping = map_file
                        print 'Found device and saved mapping'
                        break

        else:
            xbmcgui.Dialog().ok(
                    self.core.string('name'),
                    self.core.string('mapping_failure')
            )

    def init_existing_controls(self):
        if self.controls is not None:
            for key, value in self.controls.iteritems():
                self.remove_input(value, True)
            self.controls = {}

        del_keys = []
        for key, device in self.input_storage.iteritems():
            print 'Iterating saved input devices in INIT: %s' % device.name
            if not self.device_wrapper.find_device_by_name(device.name):
                print 'Could not find device by name: %s' % device.name
                del_keys.append(key)

        for key in del_keys:
            del self.input_storage[key]

        for key, device in self.input_storage.iteritems():
            self.add_ctrl(device)

    def filter_input_devices(self):
        device_list = []
        current_ctrl_labels = [ctrl.input_select_btn.getLabel() for key, ctrl in self.controls.iteritems()]
        for device in self.available_devices:
            if device.name not in current_ctrl_labels:
                device_list.append(device)
        return device_list

    def close_and_save(self):
        self.input_storage.sync()
        print self.input_storage.raw_dict()
        print 'Save called, closing window ... '
        self.close()
Esempio n. 2
0
class SkinPatcher:
    def __init__(self):
        self.core = RequiredFeature('core').request()
        self.plugin = RequiredFeature('plugin').request()
        self.base_path = '/usr/share/kodi/addons/skin.osmc/16x9/'
        self.shortcut_path = '/usr/share/kodi/addons/skin.osmc/shortcuts/'
        self.widget = 'Includes_Widgets.xml'
        self.var = 'Variables.xml'
        self.home = 'Home.xml'
        self.override = 'overrides.xml'
        self.widget_backup = 'Includes_Widgets.backup'
        self.var_backup = 'Variables.backup'
        self.home_backup = 'Home.backup'
        self.override_backup = 'overrides.backup'
        self.id = None

        self.supported = self.core.get_active_skin() == 'skin.osmc' \
            and os.path.isfile(os.path.join(self.base_path, self.widget)) \
            and os.path.isfile(os.path.join(self.base_path, self.var)) \
            and os.path.isfile(os.path.join(self.base_path, self.home)) \
            and os.path.isfile(os.path.join(self.shortcut_path, self.override))

        self.rollback_supported = os.path.isfile(os.path.join(self.base_path, self.widget_backup)) \
            and os.path.isfile(os.path.join(self.base_path, self.var_backup)) \
            and os.path.isfile(os.path.join(self.base_path, self.home_backup)) \
            and os.path.isfile(os.path.join(self.shortcut_path, self.override_backup))

    def backup(self):
        shutil.copy(os.path.join(self.base_path, self.widget), os.path.join(self.base_path, self.widget_backup))
        shutil.copy(os.path.join(self.base_path, self.var), os.path.join(self.base_path, self.var_backup))
        shutil.copy(os.path.join(self.base_path, self.home), os.path.join(self.base_path, self.home_backup))
        shutil.copy(os.path.join(self.shortcut_path, self.override),
                    os.path.join(self.shortcut_path, self.override_backup))

    def patch(self):
        if self.supported:
            self.backup()
            self.patch_widget()
            self.patch_home()
            self.patch_var()
            self.patch_override()
            self.plugin.set_setting('luna_widget_patched', 'true')
        else:
            print 'Not Supported'

    def patch_widget(self):
        xml_root = ElementTree.ElementTree(file=os.path.join(self.base_path, self.widget)).getroot()

        include = ElementTree.SubElement(xml_root, 'include', name="Luna")
        content = ElementTree.SubElement(include, 'content')

        for i in range(0, 20):
            item = ElementTree.SubElement(content, 'item')

            ElementTree.SubElement(item, 'icon').text = "$INFO[Window.Property(Luna.%s.icon)]" % i
            ElementTree.SubElement(item, 'thumb').text = "$INFO[Window.Property(Luna.%s.thumb)]" % i
            ElementTree.SubElement(item, 'label').text = "$INFO[Window.Property(Luna.%s.name)]" % i
            ElementTree.SubElement(item, 'property', name="fanart").text = "$INFO[Window.Property(Luna.%s.fanart)]" % i
            ElementTree.SubElement(item, 'onclick')\
                .text = "RunPlugin(plugin://script.luna/games/launch-from-widget/%s)" % i
            ElementTree.SubElement(item, 'visible').text = "!IsEmpty(Window.Property(Luna.%s.name))" % i

        indent(include)
        tree = ElementTree.ElementTree(xml_root)
        tree.write(os.path.join(self.base_path, self.widget))

    def patch_home(self):
        xml_root = ElementTree.ElementTree(file=os.path.join(self.base_path, self.home)).getroot()
        print self.plugin.get_setting('luna_force_fanart')

        controls = xml_root.find('controls')
        control_group = None
        for control in controls:
            print control.get('type')
            if control.get('type') == 'image':
                print "Found Image Control"
                if self.plugin.get_setting('luna_force_fanart', bool):
                    control.find('visible').text = "True"
                    print 'Visible Text is %s' % control.find('visible').text
            if control.get('type') == 'group':
                control_group = control
                break

        inner_control_group = None
        for control in control_group:
            if control.get('type') == 'group':
                inner_control_group = control_group
                break

        widget_control = None
        for control in inner_control_group:
            if control.get('type') == 'group':
                widget_control = control
                break

        inner_widget_control = None
        for control in widget_control:
            if control.get('id') is not None:
                inner_widget_control = control
                break

        current_max_id = ""
        myosmc_control = None
        for control in inner_widget_control:
            if control.get('id') is not None:
                current_max_id = control.get('id')
                myosmc_control = control

        current_max_id = int(current_max_id) + 1
        self.id = current_max_id

        luna_control = copy.deepcopy(myosmc_control)

        luna_control.set('id', str(current_max_id))
        luna_control.find('include').text = "Luna"
        luna_control.find('visible').text = "StringCompare(Container(9000).ListItem.Property(Widget),Luna)"

        luna_item_layout = luna_control.find('itemlayout')
        luna_item_layout.set('width', "270")
        luna_focus_layout = luna_control.find('focusedlayout')
        luna_focus_layout.set('width', "270")

        for control in luna_item_layout:
            if control.get('type') == 'image':
                control.find('width').text = "250"
            if control.find('texture') is not None and control.find('texture').text == 'common/black.png':
                control.find('texture').text = ""

        for control in luna_focus_layout:
            if control.get('type') == 'image':
                control.find('width').text = "250"
            if control.find('texture') is not None and control.find('texture').text == 'common/black.png':
                control.find('texture').text = ""

        inner_widget_control.append(luna_control)

        tree = ElementTree.ElementTree(xml_root)
        tree.write(os.path.join(self.base_path, self.home))

    def patch_var(self):
        xml_root = ElementTree.ElementTree(file=os.path.join(self.base_path, self.var)).getroot()

        label_group = None
        heading_group = None
        fanart_group = None

        for var in xml_root.findall('variable'):
            if var.get('name') == 'WidgetLabel':
                label_group = var
            if var.get('name') == 'WidgetHeading':
                heading_group = var
            if var.get('name') == 'WidgetFanart':
                fanart_group = var
            if label_group is not None and heading_group is not None and fanart_group is not None:
                break

        ElementTree.SubElement(label_group, "value",
                               condition="StringCompare(Container(9000).ListItem.Property(Widget),Luna)")\
            .text = "$INFO[Container(%s).ListItem.Label]" % self.id

        ElementTree.SubElement(heading_group, "value",
                               condition="StringCompare(Container(9000).ListItem.Property(Widget),Luna)")\
            .text = "Games"

        ElementTree.SubElement(fanart_group, "value",
                               condition="StringCompare(Container(9000).ListItem.Property(Widget),Luna)")\
            .text = "$INFO[Container(%s).ListItem.Property(fanart)]" % self.id

        tree = ElementTree.ElementTree(xml_root)
        tree.write(os.path.join(self.base_path, self.var))

    def patch_override(self):
        xml_root = ElementTree.ElementTree(file=os.path.join(self.shortcut_path, self.override)).getroot()

        ElementTree.SubElement(xml_root, "widget", label="Luna").text = "Luna"
        ElementTree.SubElement(xml_root, "widgetdefault", labelID="script.luna").text = "Luna"

        tree = ElementTree.ElementTree(xml_root)
        tree.write(os.path.join(self.shortcut_path, self.override))

    def rollback(self):
        if self.rollback_supported:
            shutil.move(os.path.join(self.base_path, self.widget_backup), os.path.join(self.base_path, self.widget))
            shutil.move(os.path.join(self.base_path, self.var_backup), os.path.join(self.base_path, self.var))
            shutil.move(os.path.join(self.base_path, self.home_backup), os.path.join(self.base_path, self.home))
            shutil.move(os.path.join(self.shortcut_path, self.override_backup), os.path.join(self.shortcut_path, self.override))
            self.plugin.set_setting('luna_widget_patched', 'false')
Esempio n. 3
0
class SelectInput(pyxbmct.AddonDialogWindow):
    def __init__(self, title=''):
        print 'Init Called'
        super(SelectInput, self).__init__(title)
        self.plugin = RequiredFeature('plugin').request()
        self.core = RequiredFeature('core').request()
        self.device_wrapper = RequiredFeature('device-wrapper').request()
        self.available_devices = self.device_wrapper.devices
        self.md5 = hashlib.md5()
        self.input_storage = self.plugin.get_storage('input_storage')

        for key, device in self.input_storage.iteritems():
            print 'Devices during INIT: %s' % device.name

        background = None
        if self.core.get_active_skin() == 'skin.osmc':
            media_path = '/usr/share/kodi/addons/skin.osmc/media'
            if os.path.exists(media_path):
                background = os.path.join(media_path,
                                          'dialogs/DialogBackground_old.png')

        if background is not None:
            self.background.setImage(background)
            self.removeControl(self.title_background)
            self.removeControl(self.window_close_button)
            self.removeControl(self.title_bar)

        self.controls = {}
        self.add_ctrl_btn = None

        self.setGeometry(1280, 720, 12, 6, padding=60)
        self.place_add_ctrl_btn()
        self.setFocus(self.add_ctrl_btn)
        self.connect(pyxbmct.ACTION_NAV_BACK, self.close_and_save)
        self.init_existing_controls(
        )  # initalise controls / mappings read from .storage

    def place_add_ctrl_btn(self):
        self.add_ctrl_btn = create_button()
        self.add_ctrl_btn.setLabel('Add Controller')
        self.placeControl(self.add_ctrl_btn,
                          row=12,
                          column=1,
                          rowspan=1,
                          columnspan=2)
        self.connect(self.add_ctrl_btn, self.add_ctrl)

    def add_ctrl(self, device=None):
        idx = len(self.controls)
        print 'Adding controler with index %s' % idx
        control = CtrlSelectionWrapper()
        self.md5.update(str(time.time()))
        ctrl_id = self.md5.hexdigest()
        control.id = ctrl_id
        control.idx = idx

        if not device:
            device = InputDevice()
            device.name = 'None (Disabled)'

        control.device = device

        label = create_label()
        label.setLabel('Controller ' + str(idx))
        control.label = label

        input_select_btn = create_button()
        input_select_btn.setLabel(control.device.name, )
        control.input_select_btn = input_select_btn

        trigger_adv_mapping_btn = create_button()
        trigger_adv_mapping_btn.setLabel('Add Mapping')
        control.trigger_adv_mapping_btn = trigger_adv_mapping_btn

        remove_btn = create_button()
        remove_btn.setLabel('Remove')
        control.remove_btn = remove_btn

        if idx == 0:
            row = 0
            adv_row = 1
        else:
            row = idx * 2
            adv_row = row + 1

        control.adv_row = adv_row

        self.placeControl(control.label,
                          row=row,
                          column=0,
                          rowspan=1,
                          columnspan=1)
        self.placeControl(control.input_select_btn,
                          row=row,
                          column=1,
                          rowspan=1,
                          columnspan=3)
        self.placeControl(control.trigger_adv_mapping_btn,
                          row=row,
                          column=4,
                          rowspan=1,
                          columnspan=1)
        self.placeControl(control.remove_btn,
                          row=row,
                          column=5,
                          rowspan=1,
                          columnspan=1)

        self.connect_controls(control)

        if control.device.is_kbd() or control.device.is_mouse(
        ) or control.device.is_none_device():
            trigger_adv_mapping_btn.setEnabled(False)
            # Still visible for now, but disabled
            # trigger_adv_mapping_btn.setVisible(False)

        control.set_internal_navigation()

        self.controls[control.id] = control

        # TODO: Should be a dedicated method (set_navigation)
        self.add_ctrl_btn.controlUp(control.input_select_btn)
        if control.adv_on_flag:
            control.adv_select_mapping.controlDown(self.add_ctrl_btn)
        else:
            control.input_select_btn.controlDown(self.add_ctrl_btn)
        previous_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx - 1:
                previous_control = _control
        if previous_control:
            if previous_control.adv_on_flag:
                control.input_select_btn.controlUp(
                    previous_control.adv_select_mapping)
                previous_control.adv_select_mapping.controlDown(
                    control.input_select_btn)
            else:
                control.input_select_btn.controlUp(
                    previous_control.input_select_btn)
                previous_control.input_select_btn.controlDown(
                    control.input_select_btn)

        if control.device.mapping:
            self.trigger_advanced(control)

    def connect_controls(self, control):
        self.connect(control.input_select_btn,
                     lambda: self.select_input(control))
        self.connect(control.remove_btn, lambda: self.remove_input(control))
        self.connect(control.trigger_adv_mapping_btn,
                     lambda: self.trigger_advanced(control))

    def select_input(self, control):
        available_devices = self.filter_input_devices()
        device_names = [_dev.name for _dev in available_devices]
        controller = xbmcgui.Dialog().select('Select Input Device',
                                             device_names)
        if controller == -1:
            return
        else:
            print device_names[controller]
            device = self.device_wrapper.find_device_by_name(
                device_names[controller])
            control.device = device
            control.input_select_btn.setLabel(device.name)
            if device.is_kbd() or device.is_mouse() or device.is_none_device():
                control.trigger_adv_mapping_btn.setEnabled(False)
            else:
                control.trigger_adv_mapping_btn.setEnabled(True)
            self.input_storage[control.idx] = device

    def remove_input(self, control, dry=False):
        self.removeControls(control.controls_as_list())
        del_key = None
        for key, value in self.input_storage.iteritems():
            if value.name == control.device.name:
                del_key = key
        if not dry:
            del self.input_storage[del_key]
            del self.controls[control.id]
            del control
            self.init_existing_controls()
            self.setFocus(self.add_ctrl_btn)

    def trigger_advanced(self, control):
        control.adv_on(self)
        control.set_internal_navigation()
        next_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx + 1:
                next_control = _control
        if next_control:
            control.adv_select_mapping.controlDown(
                next_control.input_select_btn)
            next_control.input_select_btn.controlUp(control.adv_select_mapping)
        else:
            control.adv_select_mapping.controlDown(self.add_ctrl_btn)
            self.add_ctrl_btn.controlUp(control.adv_select_mapping)
        self.setFocus(control.input_select_btn)

    def unset_advanced(self, control):
        control.adv_off(self)
        control.set_internal_navigation()
        control.unset_mapping_file()
        for key, device in self.input_storage.iteritems():
            if device.name == control.device.name:
                device.mapping = None
                print 'Found device and saved mapping'
                break
        next_control = None
        for _ctrl_id, _control in self.controls.iteritems():
            print 'Looping controls, current index: %s' % _control.idx
            if _control.idx == control.idx + 1:
                next_control = _control
        if next_control:
            control.input_select_btn.controlDown(next_control.input_select_btn)
            next_control.input_select_btn.controlUp(control.input_select_btn)
        else:
            control.input_select_btn.controlDown(self.add_ctrl_btn)
            self.add_ctrl_btn.controlUp(control.input_select_btn)
        self.setFocus(control.input_select_btn)

    def select_mapping(self, control):
        browser = xbmcgui.Dialog().browse(1, 'Select Mapping File', 'files',
                                          '.map|.conf', False, False,
                                          os.path.expanduser('~'))
        if browser:
            control.set_mapping_file(browser)
            for key, device in self.input_storage.iteritems():
                print 'Iterating devices, current IS device: %s' % device.name
                if device.name == control.device.name:
                    device.mapping = browser
                    print 'Found device and saved mapping'
                    break

    def create_mapping(self, control):
        print 'Starting mapping'
        map_name = xbmcgui.Dialog().input(self.core.string('enter_filename'))

        progress_dialog = xbmcgui.DialogProgress()
        progress_dialog.create(self.core.string('name'),
                               self.core.string('starting_mapping'))

        map_file = '%s/%s.map' % (os.path.expanduser('~'), map_name)

        moonlight_helper = RequiredFeature('moonlight-helper').request()
        success = moonlight_helper.create_ctrl_map_new(progress_dialog,
                                                       map_file,
                                                       control.device)

        if success:
            confirmed = xbmcgui.Dialog().yesno(
                self.core.string('name'), self.core.string('mapping_success'),
                self.core.string('set_mapping_active'))

            self.core.logger.info('Dialog Yes No Value: %s' % confirmed)

            if confirmed:
                control.set_mapping_file(map_file)
                for key, device in self.input_storage.iteritems():
                    print 'Iterating devices, current IS device: %s' % device.name
                    if device.name == control.device.name:
                        device.mapping = map_file
                        print 'Found device and saved mapping'
                        break

        else:
            xbmcgui.Dialog().ok(self.core.string('name'),
                                self.core.string('mapping_failure'))

    def init_existing_controls(self):
        if self.controls is not None:
            for key, value in self.controls.iteritems():
                self.remove_input(value, True)
            self.controls = {}

        del_keys = []
        for key, device in self.input_storage.iteritems():
            print 'Iterating saved input devices in INIT: %s' % device.name
            if not self.device_wrapper.find_device_by_name(device.name):
                print 'Could not find device by name: %s' % device.name
                del_keys.append(key)

        for key in del_keys:
            del self.input_storage[key]

        for key, device in self.input_storage.iteritems():
            self.add_ctrl(device)

    def filter_input_devices(self):
        device_list = []
        current_ctrl_labels = [
            ctrl.input_select_btn.getLabel()
            for key, ctrl in self.controls.iteritems()
        ]
        for device in self.available_devices:
            if device.name not in current_ctrl_labels:
                device_list.append(device)
        return device_list

    def close_and_save(self):
        self.input_storage.sync()
        print self.input_storage.raw_dict()
        print 'Save called, closing window ... '
        self.close()