class GusHardwareOptions(QWidget):
    def __init__(self, parent, name="GusHardwareOptions"):
        QWidget.__init__(self, parent, name)
        numrows = 2
        numcols = 3
        margin = 0
        space = 1
        self.grid = QGridLayout(self, numrows, numcols, margin, space, "GusHardwareOptionsLayout")
        self.base_box = ConfigSpinWidget(self, "I/O address", max=1000)
        self.grid.addWidget(self.base_box, 0, 0)
        self.irq1_box = ConfigSpinWidget(self, "IRQ 1", min=3, max=15)
        self.grid.addWidget(self.irq1_box, 0, 1)
        self.irq2_box = ConfigSpinWidget(self, "IRQ 2", min=3, max=15)
        self.grid.addWidget(self.irq2_box, 1, 1)
        self.dma1_box = ConfigSpinWidget(self, "DMA 1")
        self.grid.addWidget(self.dma1_box, 0, 2)
        self.dma2_box = ConfigSpinWidget(self, "DMA 2")
        self.grid.addWidget(self.dma2_box, 1, 2)

    def get_config_options(self):
        opts = {}
        opts["gusbase"] = self.base_box.get_config_option()
        opts["irq1"] = self.irq1_box.get_config_option()
        opts["irq2"] = self.irq2_box.get_config_option()
        opts["dma1"] = self.dma1_box.get_config_option()
        opts["dma2"] = self.dma2_box.get_config_option()

        return opts

    def set_config_options(self, opts):
        self.base_box.set_config_option(opts["gusbase"])
        self.irq1_box.set_config_option(opts["irq1"])
        self.irq2_box.set_config_option(opts["irq2"])
        self.dma1_box.set_config_option(opts["dma1"])
        self.dma2_box.set_config_option(opts["dma2"])
class SoundBlasterHardwareOptions(QWidget):
    def __init__(self, parent, name="SoundBlasterHardwareOptions"):
        QWidget.__init__(self, parent, name)
        numrows = 2
        numcols = 3
        margin = 0
        space = 1
        self.grid = QGridLayout(self, numrows, numcols, margin, space, "SoundBlasterHardwareOptionsLayout")
        self.base_box = ConfigSpinWidget(self, "I/O address", max=1000)
        self.grid.addWidget(self.base_box, 0, 0)
        self.irq_box = ConfigSpinWidget(self, "IRQ", min=3, max=15)
        self.grid.addWidget(self.irq_box, 1, 0)
        self.dma_box = ConfigSpinWidget(self, "DMA")
        self.grid.addWidget(self.dma_box, 0, 2)
        self.hdma_box = ConfigSpinWidget(self, "High DMA")
        self.grid.addWidget(self.hdma_box, 1, 2)

    def get_config_options(self):
        opts = {}
        opts["sbbase"] = self.base_box.get_config_option()
        opts["irq"] = self.irq_box.get_config_option()
        opts["dma"] = self.dma_box.get_config_option()
        opts["hdma"] = self.hdma_box.get_config_option()
        return opts

    def set_config_options(self, opts):
        self.base_box.set_config_option(opts["sbbase"])
        self.irq_box.set_config_option(opts["irq"])
        self.dma_box.set_config_option(opts["dma"])
        self.hdma_box.set_config_option(opts["hdma"])
class SDLConfigWidget(BaseDosboxConfigWidget):
    def __init__(self, parent, name='SDLConfigWidget'):
        BaseDosboxConfigWidget.__init__(self, parent, name=name)
        numrows = 2
        numcols = 2
        margin = 0
        space = 1
        self.grid = QGridLayout(self, numrows, numcols,
                                margin, space, 'SDLConfigWidgetLayout')
        self.myconfig = self.app.myconfig
        res = self.myconfig.get('dosbox_profiles', 'default_resolutions')
        resolutions = [r.strip() for r in res.split(',')]
        self._default_resolutions = ['original'] + resolutions
        self._default_outputs = ['surface', 'overlay', 'opengl', 'openglnb', 'ddraw']
        self._default_priorities = ['lowest', 'lower', 'normal', 'higher', 'highest']
        self.new_stuff()
        self.localconfig.add_section('sdl')
        
    def new_stuff(self):
        # fullscreen group
        self.fullscreen_groupbox = VerticalGroupBox(self, 'Fullscreen Options')
        self.fullscreen_groupbox.setColumns(2)
        self.grid.addWidget(self.fullscreen_groupbox, 0, 0)
        self.fullscreen_check = QCheckBox(self.fullscreen_groupbox)
        self.fullscreen_check.setText('fullscreen')
        self.tooltips.add(self.fullscreen_check, "Run dosbox in fullscreen")
        self.fulldouble_check = QCheckBox(self.fullscreen_groupbox)
        self.fulldouble_check.setText('full&double')
        self.tooltips.add(self.fulldouble_check, "Use double buffering in fullscreen")
        
        # resolution group
        self.resolution_groupbox = VerticalGroupBox(self, 'Resolution Options')
        self.resolution_groupbox.setColumns(4)
        self.grid.addWidget(self.resolution_groupbox, 0, 1)
        self.fullresolution_box = ConfigComboBoxWidget(self.resolution_groupbox,
                                                       'fullscreen resolution', self._default_resolutions)
        self.tooltips.add(self.fullresolution_box, "Resolution when running in fullscreen")

        self.windowresolution_box = ConfigComboBoxWidget(self.resolution_groupbox,
                                                         'windowed resolution', self._default_resolutions)
        self.tooltips.add(self.windowresolution_box, "Resolution when running in a window")
        
        # misc group
        self.misc_groupbox = VerticalGroupBox(self, 'Misc. Options')
        self.misc_groupbox.setColumns(3)
        self.grid.addWidget(self.misc_groupbox, 1, 0)
        self.output_box = ConfigComboBoxWidget(self.misc_groupbox,
                                               'Output', self._default_outputs)
        self.waitonerror_check = QCheckBox(self.misc_groupbox)
        self.waitonerror_check.setText('Wait on error')
        self.tooltips.add(self.waitonerror_check,
                          "Wait before closing window if dosbox has an error")
        
        # mouse group
        self.mouse_groupbox = VerticalGroupBox(self, 'Mouse Options')
        self.mouse_groupbox.setColumns(3)
        self.grid.addWidget(self.mouse_groupbox, 1, 1)
        self.autolock_check = QCheckBox(self.mouse_groupbox)
        self.autolock_check.setText('autolock')
        self.tooltips.add(self.autolock_check,
                          "Clicking in the dosbox window automatically locks mouse")
        self.sensitivity_box = ConfigSpinWidget(self.mouse_groupbox,
                                                'Mouse sensitivity', min=1, max=100,
                                                suffix='%')
        self.tooltips.add(self.sensitivity_box, "How sensitive the mouse is")

        # keyboard group
        self.keyboard_groupbox = VerticalGroupBox(self, 'Keyboard Options')
        self.keyboard_groupbox.setColumns(3)
        # add to row 2, first two columns
        self.grid.addMultiCellWidget(self.keyboard_groupbox, 2, 2, 0, 1)
        self.usescancodes_check = QCheckBox(self.keyboard_groupbox)
        self.usescancodes_check.setText('usescancodes')
        self.tooltips.add(self.usescancodes_check,
                          "Avoid use of symkeys")
        self.mapper_entry = ConfigKURLSelectWidget(self.keyboard_groupbox,
                                                   'mapperfile (File used for key mappings)')
        self.tooltips.add(self.mapper_entry, "File used for key mappings")


        # priority group
        self.priority_groupbox = QGroupBox(self)
        self.priority_groupbox.setTitle('Priority Options')
        self.priority_groupbox.setColumns(2)
        #self.grid.addWidget(self.priority_groupbox, 3, 0)
        # add to row 3 first two columns
        self.grid.addMultiCellWidget(self.priority_groupbox, 3, 3, 0, 1)
        self.focused_box = ConfigComboBoxWidget(self.priority_groupbox,
                                                'focused', self._default_priorities)
        self.tooltips.add(self.focused_box, "Priority level for dosbox when focused")
        self.unfocused_box = ConfigComboBoxWidget(self.priority_groupbox,
                                                  'unfocused', self._default_priorities)
        self.tooltips.add(self.unfocused_box,
                          "Priority level for dosbox when unfocused or minimized")
        
    def set_config(self, configobj):
        self.mainconfig = configobj
        # some assignments to help with typing
        sdl = 'sdl'
        cfg = self.mainconfig
        # set the various config widgets
        fullscreen = cfg.getboolean(sdl, 'fullscreen')
        self.fullscreen_check.setChecked(fullscreen)
        fulldouble = cfg.getboolean(sdl, 'fulldouble')
        self.fulldouble_check.setChecked(fulldouble)
        fullresolution = cfg.get(sdl, 'fullresolution')
        self.fullresolution_box.set_config_option(fullresolution)
        windowresolution = cfg.get(sdl, 'windowresolution')
        self.windowresolution_box.set_config_option(windowresolution)
        output = cfg.get(sdl, 'output')
        self.output_box.set_config_option(output)
        waitonerror = cfg.getboolean(sdl, 'waitonerror')
        self.waitonerror_check.setChecked(waitonerror)
        autolock = cfg.getboolean(sdl, 'autolock')
        self.autolock_check.setChecked(autolock)
        sensitivity = cfg.getint(sdl, 'sensitivity')
        self.sensitivity_box.set_config_option(sensitivity)
        usescancodes = cfg.getboolean(sdl, 'usescancodes')
        self.usescancodes_check.setChecked(usescancodes)
        mapperfile = cfg.get(sdl, 'mapperfile')
        self.mapper_entry.set_config_option(mapperfile)
        priorities = cfg.get(sdl, 'priority')
        focused, unfocused = [p.strip() for p in priorities.split(',')]
        self.focused_box.set_config_option(focused)
        self.unfocused_box.set_config_option(unfocused)

    def get_config(self):
        # some assignments to help with typing
        sdl = 'sdl'
        cfg = self.localconfig
        # get config values from the various widgets
        fullscreen = self._get_bool_for_config(self.fullscreen_check)
        cfg.set(sdl, 'fullscreen', fullscreen)
        fulldouble = self._get_bool_for_config(self.fulldouble_check)
        cfg.set(sdl, 'fulldouble', fulldouble)
        fullresolution = self.fullresolution_box.get_config_option()
        cfg.set(sdl, 'fullresolution', fullresolution)
        windowresolution = self.windowresolution_box.get_config_option()
        cfg.set(sdl, 'windowresolution', windowresolution)
        output = self.output_box.get_config_option()
        cfg.set(sdl, 'output', output)
        waitonerror = self._get_bool_for_config(self.waitonerror_check)
        cfg.set(sdl, 'waitonerror', waitonerror)
        autolock = self._get_bool_for_config(self.autolock_check)
        cfg.set(sdl, 'autolock', autolock)
        sensitivity = self.sensitivity_box.get_config_option()
        cfg.set(sdl, 'sensitivity', sensitivity)
        usescancodes = self._get_bool_for_config(self.usescancodes_check)
        cfg.set(sdl, 'usescancodes', usescancodes)
        mapperfile = self.mapper_entry.get_config_option()
        cfg.set(sdl, 'mapperfile', mapperfile)
        # priorities part
        focused = self.focused_box.get_config_option()
        unfocused = self.unfocused_box.get_config_option()
        priority = ','.join([focused, unfocused])
        cfg.set(sdl, 'priority', priority)
        return self.localconfig
class SoundConfigWidget(BaseDosboxConfigWidget):
    def __init__(self, parent, name="SDLConfigWidget"):
        BaseDosboxConfigWidget.__init__(self, parent, name=name)
        numrows = 2
        numcols = 3
        margin = 10
        space = 7
        self._default_mpu401_types = ["none", "uart", "intelligent"]
        self._default_midi_devices = ["default", "none", "alsa", "oss", "coreaudio", "win32"]
        self._default_sbtypes = ["none", "sb1", "sb2", "sbpro1", "sbpro2", "sb16"]
        self._default_tandyopts = ["auto", "on", "off"]
        self.grid = QGridLayout(self, numrows, numcols, margin, space, "SDLConfigWidgetLayout")
        for section in ["mixer", "midi", "sblaster", "gus", "speaker"]:
            self.localconfig.add_section(section)

        # mixer group
        self.mixer_groupbox = VerticalGroupBox(self, "Mixer Options")
        self.mixer_groupbox.setColumns(4)
        self.grid.addWidget(self.mixer_groupbox, 0, 0)
        self.nosound_check = QCheckBox(self.mixer_groupbox)
        self.nosound_check.setText("Disable sound")
        self.sample_rate_box = SampleRateOption(self.mixer_groupbox, "Sample rate")
        # magic number for maximum block size
        self.blocksize_box = ConfigSpinWidget(
            self.mixer_groupbox, "Mixer block size", min=0, max=262144, suffix=" bytes"
        )
        # magic number for maximum prebuffer (10 secs)
        self.prebuffer_box = ConfigSpinWidget(self.mixer_groupbox, "Prebuffer", min=0, max=10000, suffix=" msec")

        # midi group
        self.midi_groupbox = VerticalGroupBox(self, "MIDI Options")
        self.midi_groupbox.setColumns(4)
        self.grid.addWidget(self.midi_groupbox, 1, 1)
        self.mpu401_box = ConfigComboBoxWidget(self.midi_groupbox, "mpu401 type", self._default_mpu401_types)
        self.midi_device_box = ConfigComboBoxWidget(self.midi_groupbox, "MIDI device", self._default_midi_devices)
        self.midi_config_box = ConfigLineEditWidget(self.midi_groupbox, "MIDI config")

        # speaker group
        self.speaker_groupbox = VerticalGroupBox(self, "PC Speaker Options")
        self.speaker_groupbox.setColumns(5)
        self.grid.addMultiCellWidget(self.speaker_groupbox, 1, 1, 0, 0)
        self.enable_speaker_check = QCheckBox(self.speaker_groupbox)
        self.enable_speaker_check.setText("Enable PC speaker emulation")
        self.pc_rate_box = SampleRateOption(self.speaker_groupbox, "Sample rate of PC speaker")
        self.enable_tandy_box = ConfigComboBoxWidget(
            self.speaker_groupbox, "Enable Tandy Sound System emulation", self._default_tandyopts
        )
        self.tandy_rate_box = SampleRateOption(self.speaker_groupbox, "Sample rate of Tandy Sound System")
        self.enable_disney_check = QCheckBox(self.speaker_groupbox)
        self.enable_disney_check.setText("Enable Disney Sound Source emulation")

        # sblaster group
        self.sblaster_groupbox = VerticalGroupBox(self, "SoundBlaster Options")
        self.sblaster_groupbox.setColumns(2)
        # self.grid.addWidget(self.sblaster_groupbox, 0, 0)
        self.grid.addMultiCellWidget(self.sblaster_groupbox, 0, 0, 0, 1)
        self.sbtype_box = ConfigComboBoxWidget(self.sblaster_groupbox, "SoundBlaster type", self._default_sbtypes)
        self.sblaster_hwopt_groupbox = VerticalGroupBox(self.sblaster_groupbox, "SoundBlaster Hardware Options")
        self.sblaster_hwopt_groupbox.setColumns(1)
        self.sblaster_hwopt_box = SoundBlasterHardwareOptions(self.sblaster_hwopt_groupbox)

        self.sb_mixer_check = QCheckBox(self.sblaster_groupbox)
        self.sb_mixer_check.setText("SoundBlaster modifies dosbox mixer")
        self.sblaster_oplopt_groupbox = VerticalGroupBox(self.sblaster_groupbox, "SoundBlaster OPL Options")
        self.sblaster_oplopt_groupbox.setColumns(1)
        self.sblaster_oplopt_box = SoundBlasterOPLOptions(self.sblaster_oplopt_groupbox)

        # gus group
        self.gus_groupbox = VerticalGroupBox(self, "Gravis Ultrasound Options")
        self.gus_groupbox.setColumns(5)
        # self.grid.addWidget(self.gus_groupbox, 2, 1)
        self.grid.addMultiCellWidget(self.gus_groupbox, 0, 1, 2, 2)
        self.enable_gus_check = QCheckBox(self.gus_groupbox)
        self.enable_gus_check.setText("Enable Gravis Ultrasound emulation")
        self.gus_hwopt_groupbox = VerticalGroupBox(self.gus_groupbox, "Gravis Ultrasound hardware options")
        self.gus_hwopt_groupbox.setColumns(1)
        self.gus_hwopt_box = GusHardwareOptions(self.gus_hwopt_groupbox)
        self.gus_rate_box = SampleRateOption(self.gus_groupbox)
        self.gus_ultradir_box = ConfigKURLSelectWidget(self.gus_groupbox, "GUS patches directory", filetype="dir")

    def set_config(self, configobj):
        self.mainconfig = configobj
        # some assignments to help with typing
        mixer = "mixer"
        midi = "midi"
        sblaster = "sblaster"
        gus = "gus"
        speaker = "speaker"
        cfg = self.mainconfig
        # set the various config widgets
        # mixer section
        nosound = cfg.getboolean(mixer, "nosound")
        self.nosound_check.setChecked(nosound)
        rate = cfg.getint(mixer, "rate")
        self.sample_rate_box.set_config_option(rate)
        blocksize = cfg.getint(mixer, "blocksize")
        self.blocksize_box.set_config_option(blocksize)
        prebuffer = cfg.getint(mixer, "prebuffer")
        self.prebuffer_box.set_config_option(prebuffer)
        # midi section
        mpu401 = cfg.get(midi, "mpu401")
        self.mpu401_box.set_config_option(mpu401)
        device = cfg.get(midi, "device")
        self.midi_device_box.set_config_option(device)
        midi_config = cfg.get(midi, "config")
        self.midi_config_box.set_config_option(midi_config)
        # sblaster section
        sbtype = cfg.get(sblaster, "sbtype")
        self.sbtype_box.set_config_option(sbtype)
        opts = {}
        for opt in ["sbbase", "irq", "dma", "hdma"]:
            opts[opt] = cfg.getint(sblaster, opt)
        self.sblaster_hwopt_box.set_config_options(opts)
        mixer = cfg.getboolean(sblaster, "mixer")
        self.sb_mixer_check.setChecked(mixer)
        opts = {}
        opts["oplmode"] = cfg.get(sblaster, "oplmode")
        opts["oplrate"] = cfg.getint(sblaster, "oplrate")
        self.sblaster_oplopt_box.set_config_options(opts)

        # gus section
        enable_gus = cfg.getboolean(gus, "gus")
        self.enable_gus_check.setChecked(enable_gus)
        gusrate = cfg.getint(gus, "gusrate")
        self.gus_rate_box.set_config_option(gusrate)
        opts = {}
        for opt in ["gusbase", "irq1", "irq2", "dma1", "dma2"]:
            opts[opt] = cfg.getint(gus, opt)
        self.gus_hwopt_box.set_config_options(opts)
        ultradir = cfg.get(gus, "ultradir")
        self.gus_ultradir_box.set_config_option(ultradir)
        # speaker section
        pcspeaker = cfg.getboolean(speaker, "pcspeaker")
        self.enable_speaker_check.setChecked(pcspeaker)
        pcrate = cfg.getint(speaker, "pcrate")
        self.pc_rate_box.set_config_option(pcrate)
        tandy = cfg.get(speaker, "tandy")
        self.enable_tandy_box.set_config_option(tandy)
        tandyrate = cfg.getint(speaker, "tandyrate")
        self.tandy_rate_box.set_config_option(tandyrate)
        disney = cfg.getboolean(speaker, "disney")
        self.enable_disney_check.setChecked(disney)

    def get_config(self):
        # some assignments to help with typing
        mixer = "mixer"
        midi = "midi"
        sblaster = "sblaster"
        gus = "gus"
        speaker = "speaker"
        cfg = self.localconfig
        # get config values from the various widgets
        # mixer section
        nosound = self._get_bool_for_config(self.nosound_check)
        cfg.set(mixer, "nosound", nosound)
        rate = self.sample_rate_box.get_config_option()
        cfg.set(mixer, "rate", rate)
        blocksize = self.blocksize_box.get_config_option()
        cfg.set(mixer, "blocksize", blocksize)
        prebuffer = self.prebuffer_box.get_config_option()
        cfg.set(mixer, "prebuffer", prebuffer)
        # midi section
        mpu401 = self.mpu401_box.get_config_option()
        cfg.set(midi, "mpu401", mpu401)
        device = self.midi_device_box.get_config_option()
        cfg.set(midi, "device", device)
        midi_config = self.midi_config_box.get_config_option()
        cfg.set(midi, "config", midi_config)
        # sblaster section
        sbtype = self.sbtype_box.get_config_option()
        cfg.set(sblaster, "sbtype", sbtype)
        opts = self.sblaster_hwopt_box.get_config_options()
        for opt, value in opts.items():
            cfg.set(sblaster, opt, value)
        mixer = self._get_bool_for_config(self.sb_mixer_check)
        cfg.set(sblaster, "mixer", mixer)
        opts = self.sblaster_oplopt_box.get_config_options()
        for opt, value in opts.items():
            cfg.set(sblaster, opt, value)
        # gus section
        enable_gus = self._get_bool_for_config(self.enable_gus_check)
        cfg.set(gus, "gus", enable_gus)
        gusrate = self.gus_rate_box.get_config_option()
        cfg.set(gus, "gusrate", gusrate)
        opts = self.gus_hwopt_box.get_config_options()
        for opt, value in opts.items():
            cfg.set(gus, opt, value)
        ultradir = self.gus_ultradir_box.get_config_option()
        cfg.set(gus, "ultradir", ultradir)
        # speaker section
        pcspeaker = self._get_bool_for_config(self.enable_speaker_check)
        cfg.set(speaker, "pcspeaker", pcspeaker)
        pcrate = self.pc_rate_box.get_config_option()
        cfg.set(speaker, "pcrate", pcrate)
        tandy = self.enable_tandy_box.get_config_option()
        cfg.set(speaker, "tandy", tandy)
        tandyrate = self.tandy_rate_box.get_config_option()
        cfg.set(speaker, "tandyrate", tandyrate)
        disney = self._get_bool_for_config(self.enable_disney_check)
        cfg.set(speaker, "disney", disney)
        # done
        return self.localconfig
class MachineConfigWidget(BaseDosboxConfigWidget):
    def __init__(self, parent, name="SDLConfigWidget"):
        BaseDosboxConfigWidget.__init__(self, parent, name=name)
        numrows = 2
        numcols = 3
        margin = 10
        space = 7
        self._default_machines = ["vga", "cga", "tandy", "pcjr", "hercules"]
        self._default_scalers = [
            "none",
            "normal2x",
            "normal3x",
            "advmame2x",
            "advmame3x",
            "advinterp2x",
            "advinterp3x",
            "tv2x",
            "tv3x",
            "rgb2x",
            "rgb3x",
            "scan2x",
            "scan3x",
        ]
        self._default_cores = ["simple", "normal", "full", "dynamic"]
        for section in ["render", "cpu", "dosbox", "dos", "bios", "serial", "ipx"]:
            self.localconfig.add_section(section)
        self.grid = QGridLayout(self, numrows, numcols, margin, space, "MachineConfigWidgetLayout")

        # render group
        self.render_groupbox = VerticalGroupBox(self, "Render Options")
        self.render_groupbox.setColumns(2)
        self.grid.addWidget(self.render_groupbox, 0, 1)
        self.frameskip_box = ConfigSpinWidget(self.render_groupbox, "Frame skip", suffix=" frames")
        self.tooltips.add(self.frameskip_box, "How many frames to skip.")
        self.aspect_check = QCheckBox(self.render_groupbox)
        self.aspect_check.setText("Aspect correction")
        self.tooltips.add(self.aspect_check, "Try to keep aspect ratio.")
        self.scaler_box = ConfigComboBoxWidget(self.render_groupbox, "Scaler", self._default_scalers)
        self.tooltips.add(self.scaler_box, "Select size and effect of video")
        # cpu group
        # make a big number for cycles that should never be needed
        cyclemax = int(1e6)
        self.cpu_groupbox = VerticalGroupBox(self, "CPU Options")
        self.cpu_groupbox.setColumns(2)
        self.grid.addWidget(self.cpu_groupbox, 0, 0)
        self.core_box = ConfigComboBoxWidget(self.cpu_groupbox, "Core", self._default_cores)
        self.tooltips.add(self.core_box, "Select type of cpu core")
        self.cycles_box = ConfigSpinWidget(self.cpu_groupbox, "Cycles", max=cyclemax, suffix=" cycles")
        tt = "The number of cycles to attempt to perform in a second"
        self.tooltips.add(self.cycles_box, tt)
        self.cycleup_box = ConfigSpinWidget(self.cpu_groupbox, "Cycle up increment", max=cyclemax, suffix=" cycles")
        self.cycledown_box = ConfigSpinWidget(self.cpu_groupbox, "Cycle down increment", max=cyclemax, suffix=" cycles")

        # dosbox group
        self.dosbox_groupbox = VerticalGroupBox(self, "Dosbox Options")
        self.dosbox_groupbox.setColumns(3)
        # row 1, first two columns
        # self.grid.addMultiCellWidget(self.dosbox_groupbox, 1, 1, 0, 1)
        self.grid.addWidget(self.dosbox_groupbox, 1, 0)
        self.language_entry = ConfigKURLSelectWidget(self.dosbox_groupbox, "Language file")
        self.memsize_box = ConfigSpinWidget(self.dosbox_groupbox, "Memory size", suffix="MB")
        self.captures_entry = ConfigKURLSelectWidget(self.dosbox_groupbox, "Captures directory", filetype="dir")

        # dos group
        self.dos_groupbox = VerticalGroupBox(self, "Dos Options")
        self.dos_groupbox.setColumns(3)
        self.grid.addWidget(self.dos_groupbox, 1, 1)
        self.xms_check = QCheckBox(self.dos_groupbox)
        self.xms_check.setText("Enable XMS support")
        self.ems_check = QCheckBox(self.dos_groupbox)
        self.ems_check.setText("Enable EMS support")
        self.umb_check = QCheckBox(self.dos_groupbox)
        self.umb_check.setText("Enable UMB support")

        # peripheral options
        self.peripheral_groupbox = VerticalGroupBox(self, "Peripheral Options")
        self.peripheral_groupbox.setColumns(1)
        # self.grid.addWidget(self.peripheral_groupbox, 2, 0)
        self.grid.addMultiCellWidget(self.peripheral_groupbox, 2, 2, 0, 2)
        # peripherals in bios section
        self.bios_groupbox = VerticalGroupBox(self.peripheral_groupbox, "Bios Options")
        self.bios_groupbox.setColumns(1)
        joystick_types = ["none", "2axis", "4axis", "fcs", "ch"]
        self.joysticktype_box = ConfigComboBoxWidget(self.bios_groupbox, "Joystick type", joystick_types)
        # peripherals in serial section
        self.serial_groupbox = VerticalGroupBox(self.peripheral_groupbox, "Serial Options")
        self.serial_groupbox.setColumns(2)
        self.serial_warning_lbl = QLabel("These options are", self.serial_groupbox)
        self.serial_warning_lbl2 = QLabel("not fully suported yet.", self.serial_groupbox)
        self.serial1_box = SerialPortOption(self.serial_groupbox, "Serial 1")
        self.serial2_box = SerialPortOption(self.serial_groupbox, "Serial 2")
        self.serial3_box = SerialPortOption(self.serial_groupbox, "Serial 3")
        self.serial4_box = SerialPortOption(self.serial_groupbox, "Serial 4")

        # ipx options
        self.ipx_groupbox = VerticalGroupBox(self, "IPX Options")
        self.ipx_groupbox.setColumns(1)
        self.grid.addWidget(self.ipx_groupbox, 1, 2)
        self.ipx_check = QCheckBox(self.ipx_groupbox)
        self.ipx_check.setText("Enable ipx over UDP/IP emulation")

    def set_config(self, configobj):
        self.mainconfig = configobj
        # some assignments to help with typing
        render = "render"
        cpu = "cpu"
        dosbox = "dosbox"
        dos = "dos"
        bios = "bios"
        serial = "serial"
        ipx = "ipx"
        cfg = self.mainconfig
        # set the various config widgets
        # render section
        frameskip = cfg.getint(render, "frameskip")
        self.frameskip_box.set_config_option(frameskip)
        aspect = cfg.getboolean(render, "aspect")
        self.aspect_check.setChecked(aspect)
        scaler = cfg.get(render, "scaler")
        self.scaler_box.set_config_option(scaler)
        # cpu section
        core = cfg.get(cpu, "core")
        self.core_box.set_config_option(core)
        cycles = cfg.getint(cpu, "cycles")
        self.cycles_box.set_config_option(cycles)
        cycleup = cfg.getint(cpu, "cycleup")
        self.cycleup_box.set_config_option(cycleup)
        cycledown = cfg.getint(cpu, "cycledown")
        self.cycledown_box.set_config_option(cycledown)
        # dosbox section
        language = cfg.get(dosbox, "language")
        self.language_entry.set_config_option(language)
        memsize = cfg.getint(dosbox, "memsize")
        self.memsize_box.set_config_option(memsize)
        captures = cfg.get(dosbox, "captures")
        self.captures_entry.set_config_option(captures)
        # dos section
        xms = cfg.getboolean(dos, "xms")
        self.xms_check.setChecked(xms)
        ems = cfg.getboolean(dos, "ems")
        self.ems_check.setChecked(ems)
        umb = cfg.getboolean(dos, "umb")
        self.umb_check.setChecked(umb)
        # bios section
        joysticktype = cfg.get(bios, "joysticktype")
        self.joysticktype_box.set_config_option(joysticktype)
        # serial section
        serial1 = cfg.get(serial, "serial1")
        self.serial1_box.set_config_option(serial1)
        serial2 = cfg.get(serial, "serial2")
        self.serial2_box.set_config_option(serial2)
        serial3 = cfg.get(serial, "serial3")
        self.serial3_box.set_config_option(serial3)
        serial4 = cfg.get(serial, "serial4")
        self.serial4_box.set_config_option(serial4)
        # ipx section
        ipxopt = cfg.getboolean(ipx, ipx)
        self.ipx_check.setChecked(ipxopt)

    def get_config(self):
        # some assignments to help with typing
        render = "render"
        cpu = "cpu"
        dosbox = "dosbox"
        dos = "dos"
        bios = "bios"
        serial = "serial"
        ipx = "ipx"
        cfg = self.localconfig
        # get config values from the various widgets
        # render section
        frameskip = self.frameskip_box.get_config_option()
        cfg.set(render, "frameskip", frameskip)
        aspect = self._get_bool_for_config(self.aspect_check)
        cfg.set(render, "aspect", aspect)
        scaler = self.scaler_box.get_config_option()
        cfg.set(render, "scaler", scaler)
        # cpu section
        core = self.core_box.get_config_option()
        cfg.set(cpu, "core", core)
        cycles = self.cycles_box.get_config_option()
        cfg.set(cpu, "cycles", cycles)
        cycleup = self.cycleup_box.get_config_option()
        cfg.set(cpu, "cycleup", cycleup)
        cycledown = self.cycledown_box.get_config_option()
        cfg.set(cpu, "cycledown", cycledown)
        # dosbox section
        language = self.language_entry.get_config_option()
        cfg.set(dosbox, "language", language)
        memsize = self.memsize_box.get_config_option()
        cfg.set(dosbox, "memsize", memsize)
        captures = self.captures_entry.get_config_option()
        cfg.set(dosbox, "captures", captures)
        # dos section
        xms = self._get_bool_for_config(self.xms_check)
        cfg.set(dos, "xms", xms)
        ems = self._get_bool_for_config(self.ems_check)
        cfg.set(dos, "ems", ems)
        umb = self._get_bool_for_config(self.umb_check)
        cfg.set(dos, "umb", umb)
        # bios section
        joysticktype = self.joysticktype_box.get_config_option()
        cfg.set(bios, "joysticktype", joysticktype)
        # serial section
        serial1 = self.serial1_box.get_config_option()
        cfg.set(serial, "serial1", serial1)
        serial2 = self.serial2_box.get_config_option()
        cfg.set(serial, "serial2", serial2)
        serial3 = self.serial3_box.get_config_option()
        cfg.set(serial, "serial3", serial3)
        serial4 = self.serial4_box.get_config_option()
        cfg.set(serial, "serial4", serial4)
        # ipx section
        ipxopt = self._get_bool_for_config(self.ipx_check)
        cfg.set(ipx, ipx, ipxopt)
        return self.localconfig
class MachineConfigWidget(BaseDosboxConfigWidget):
    def __init__(self, parent, name='SDLConfigWidget'):
        BaseDosboxConfigWidget.__init__(self, parent, name=name)
        numrows = 2
        numcols = 3
        margin = 10
        space = 7
        self._default_machines = ['vga', 'cga', 'tandy', 'pcjr', 'hercules']
        self._default_scalers = ['none', 'normal2x', 'normal3x', 'advmame2x', 'advmame3x',
                                 'advinterp2x', 'advinterp3x', 'tv2x', 'tv3x',
                                 'rgb2x', 'rgb3x', 'scan2x', 'scan3x']
        self._default_cores = ['simple', 'normal', 'full', 'dynamic', 'auto']
        for section in ['render', 'cpu', 'dosbox', 'dos', 'bios', 'serial', 'ipx']:
            self.localconfig.add_section(section)
        self.grid = QGridLayout(self, numrows, numcols,
                                margin, space, 'MachineConfigWidgetLayout')

        # render group
        self.render_groupbox = VerticalGroupBox(self, 'Render Options')
        self.render_groupbox.setColumns(2)
        self.grid.addWidget(self.render_groupbox, 0, 1)
        self.frameskip_box = ConfigSpinWidget(self.render_groupbox,
                                              'Frame skip', suffix=' frames')
        self.tooltips.add(self.frameskip_box, 'How many frames to skip.')
        self.aspect_check = QCheckBox(self.render_groupbox)
        self.aspect_check.setText('Aspect correction')
        self.tooltips.add(self.aspect_check, 'Try to keep aspect ratio.')
        self.scaler_box = ConfigComboBoxWidget(self.render_groupbox,
                                               'Scaler', self._default_scalers)
        self.tooltips.add(self.scaler_box, 'Select size and effect of video')
        # cpu group
        # make a big number for cycles that should never be needed
        cyclemax = int(1e6)
        self.cpu_groupbox = VerticalGroupBox(self, 'CPU Options')
        self.cpu_groupbox.setColumns(2)
        self.grid.addWidget(self.cpu_groupbox, 0, 0)
        self.core_box = ConfigComboBoxWidget(self.cpu_groupbox,
                                             'Core', self._default_cores)
        self.tooltips.add(self.core_box, 'Select type of cpu core')
        self.cycles_box = ConfigSpinWidget(self.cpu_groupbox,
                                           'Cycles', max=cyclemax, suffix=' cycles')
        tt = 'The number of cycles to attempt to perform in a second'
        self.tooltips.add(self.cycles_box, tt)
        self.cycleup_box = ConfigSpinWidget(self.cpu_groupbox,
                                            'Cycle up increment', max=cyclemax,
                                            suffix=' cycles')
        self.cycledown_box = ConfigSpinWidget(self.cpu_groupbox,
                                              'Cycle down increment', max=cyclemax,
                                              suffix=' cycles')
        
        # dosbox group
        self.dosbox_groupbox = VerticalGroupBox(self, 'Dosbox Options')
        self.dosbox_groupbox.setColumns(3)
        # row 1, first two columns
        #self.grid.addMultiCellWidget(self.dosbox_groupbox, 1, 1, 0, 1)
        self.grid.addWidget(self.dosbox_groupbox, 1, 0)
        self.language_entry = ConfigKURLSelectWidget(self.dosbox_groupbox,
                                                     'Language file')
        self.memsize_box = ConfigSpinWidget(self.dosbox_groupbox,
                                            'Memory size', suffix='MB')
        self.captures_entry = ConfigKURLSelectWidget(self.dosbox_groupbox,
                                                     'Captures directory', filetype='dir')
            
        # dos group
        self.dos_groupbox = VerticalGroupBox(self, 'Dos Options')
        self.dos_groupbox.setColumns(3)
        self.grid.addWidget(self.dos_groupbox, 1, 1)
        self.xms_check = QCheckBox(self.dos_groupbox)
        self.xms_check.setText('Enable XMS support')
        self.ems_check = QCheckBox(self.dos_groupbox)
        self.ems_check.setText('Enable EMS support')
        self.umb_check = QCheckBox(self.dos_groupbox)
        self.umb_check.setText('Enable UMB support')

        # peripheral options
        self.peripheral_groupbox = VerticalGroupBox(self, 'Peripheral Options')
        self.peripheral_groupbox.setColumns(1)
        #self.grid.addWidget(self.peripheral_groupbox, 2, 0)
        self.grid.addMultiCellWidget(self.peripheral_groupbox, 2, 2, 0, 2)
        # peripherals in bios section
        self.bios_groupbox = VerticalGroupBox(self.peripheral_groupbox, 'Bios Options')
        self.bios_groupbox.setColumns(1)
        joystick_types = ['none', '2axis', '4axis', 'fcs', 'ch']
        self.joysticktype_box = ConfigComboBoxWidget(self.bios_groupbox,
                                                     'Joystick type', joystick_types)
        # peripherals in serial section
        self.serial_groupbox = VerticalGroupBox(self.peripheral_groupbox, 'Serial Options')
        self.serial_groupbox.setColumns(2)
        self.serial_warning_lbl = QLabel('These options are',
                                         self.serial_groupbox)
        self.serial_warning_lbl2 = QLabel('not fully suported yet.', self.serial_groupbox)
        self.serial1_box = SerialPortOption(self.serial_groupbox, 'Serial 1')
        self.serial2_box = SerialPortOption(self.serial_groupbox, 'Serial 2')
        self.serial3_box = SerialPortOption(self.serial_groupbox, 'Serial 3')
        self.serial4_box = SerialPortOption(self.serial_groupbox, 'Serial 4')

        # ipx options
        self.ipx_groupbox = VerticalGroupBox(self, 'IPX Options')
        self.ipx_groupbox.setColumns(1)
        self.grid.addWidget(self.ipx_groupbox, 1, 2)
        self.ipx_check = QCheckBox(self.ipx_groupbox)
        self.ipx_check.setText('Enable ipx over UDP/IP emulation')
        
    def set_config(self, configobj):
        self.mainconfig = configobj
        # some assignments to help with typing
        render = 'render'
        cpu = 'cpu'
        dosbox = 'dosbox'
        dos = 'dos'
        bios = 'bios'
        serial = 'serial'
        ipx = 'ipx'
        cfg = self.mainconfig
        # set the various config widgets
        # render section
        frameskip = cfg.getint(render, 'frameskip')
        self.frameskip_box.set_config_option(frameskip)
        aspect = cfg.getboolean(render, 'aspect')
        self.aspect_check.setChecked(aspect)
        scaler = cfg.get(render, 'scaler')
        self.scaler_box.set_config_option(scaler)
        # cpu section
        core = cfg.get(cpu, 'core')
        self.core_box.set_config_option(core)
        cycles = cfg.getint(cpu, 'cycles')
        self.cycles_box.set_config_option(cycles)
        cycleup = cfg.getint(cpu, 'cycleup')
        self.cycleup_box.set_config_option(cycleup)
        cycledown = cfg.getint(cpu, 'cycledown')
        self.cycledown_box.set_config_option(cycledown)
        # dosbox section
        language = cfg.get(dosbox, 'language')
        self.language_entry.set_config_option(language)
        memsize = cfg.getint(dosbox, 'memsize')
        self.memsize_box.set_config_option(memsize)
        captures = cfg.get(dosbox, 'captures')
        self.captures_entry.set_config_option(captures)
        # dos section
        xms = cfg.getboolean(dos, 'xms')
        self.xms_check.setChecked(xms)
        ems = cfg.getboolean(dos, 'ems')
        self.ems_check.setChecked(ems)
        umb = cfg.getboolean(dos, 'umb')
        self.umb_check.setChecked(umb)
        # bios section
        joysticktype = cfg.get(bios, 'joysticktype')
        self.joysticktype_box.set_config_option(joysticktype)
        # serial section
        serial1 = cfg.get(serial, 'serial1')
        self.serial1_box.set_config_option(serial1)
        serial2 = cfg.get(serial, 'serial2')
        self.serial2_box.set_config_option(serial2)
        serial3 = cfg.get(serial, 'serial3')
        self.serial3_box.set_config_option(serial3)
        serial4 = cfg.get(serial, 'serial4')
        self.serial4_box.set_config_option(serial4)
        # ipx section
        ipxopt = cfg.getboolean(ipx, ipx)
        self.ipx_check.setChecked(ipxopt)

    def get_config(self):
        # some assignments to help with typing
        render = 'render'
        cpu = 'cpu'
        dosbox = 'dosbox'
        dos = 'dos'
        bios = 'bios'
        serial = 'serial'
        ipx = 'ipx'
        cfg = self.localconfig
        # get config values from the various widgets
        # render section
        frameskip = self.frameskip_box.get_config_option()
        cfg.set(render, 'frameskip', frameskip)
        aspect = self._get_bool_for_config(self.aspect_check)
        cfg.set(render, 'aspect', aspect)
        scaler = self.scaler_box.get_config_option()
        cfg.set(render, 'scaler', scaler)
        # cpu section
        core = self.core_box.get_config_option()
        cfg.set(cpu, 'core', core)
        cycles = self.cycles_box.get_config_option()
        cfg.set(cpu, 'cycles', cycles)
        cycleup = self.cycleup_box.get_config_option()
        cfg.set(cpu, 'cycleup', cycleup)
        cycledown = self.cycledown_box.get_config_option()
        cfg.set(cpu, 'cycledown', cycledown)
        # dosbox section
        language = self.language_entry.get_config_option()
        cfg.set(dosbox, 'language', language)
        memsize = self.memsize_box.get_config_option()
        cfg.set(dosbox, 'memsize', memsize)
        captures = self.captures_entry.get_config_option()
        cfg.set(dosbox, 'captures', captures)
        # dos section
        xms = self._get_bool_for_config(self.xms_check)
        cfg.set(dos, 'xms', xms)
        ems = self._get_bool_for_config(self.ems_check)
        cfg.set(dos, 'ems', ems)
        umb = self._get_bool_for_config(self.umb_check)
        cfg.set(dos, 'umb', umb)
        # bios section
        joysticktype = self.joysticktype_box.get_config_option()
        cfg.set(bios, 'joysticktype', joysticktype)
        # serial section
        serial1 = self.serial1_box.get_config_option()
        cfg.set(serial, 'serial1', serial1)
        serial2 = self.serial2_box.get_config_option()
        cfg.set(serial, 'serial2', serial2)
        serial3 = self.serial3_box.get_config_option()
        cfg.set(serial, 'serial3', serial3)
        serial4 = self.serial4_box.get_config_option()
        cfg.set(serial, 'serial4', serial4)
        # ipx section
        ipxopt = self._get_bool_for_config(self.ipx_check)
        cfg.set(ipx, ipx, ipxopt)
        return self.localconfig