# Editing Settings of a Guest
use strict;
use warnings;

our (%gui, %signal, %hostspec, %ETruth, %EAudioDriverType, %EAudioControllerType, %ENetworkAttachmentType,
     %ENetworkAdapterType, %osfamily, %osversion, %sensgrp, $EIMachineM, %EMediumVariant);

sub show_shared_dialog() {
    my ($widget) = @_;

    if ($widget eq $gui{buttonEditSharedEdit}) {
        my %share = &getsel_list_editshared();
        $gui{entrySharedFolderPath}->set_text($share{Folder});
        $gui{entrySharedFolderName}->set_text($share{Name});

        if ($share{Access} eq 'Read-Only') { $gui{checkbuttonSharedFolderRO}->set_active(1); }
        else { $gui{checkbuttonSharedFolderRO}->set_active(0); }

        if ($share{Mount} eq 'Yes') { $gui{checkbuttonSharedFolderMount}->set_active(1); }
        else { $gui{checkbuttonSharedFolderMount}->set_active(0); }
    }

    my $response = $gui{dialogShared}->run;
    $gui{dialogShared}->hide;

    if ($response eq 'ok') {
        my $path = $gui{entrySharedFolderPath}->get_text();
        my $name = $gui{entrySharedFolderName}->get_text();
        if (!$path or !$name) { &show_err_msg('emptynamepath', $gui{messagedialogError}); }
        else {
            remove_shared($widget, $gui{treeviewEditShared}) if ($widget eq $gui{buttonEditSharedEdit});
            IMachine_createSharedFolder($EIMachineM, $name, $path, !$gui{checkbuttonSharedFolderRO}->get_active(), $gui{checkbuttonSharedFolderMount}->get_active());
            &fill_list_editshared($EIMachineM);
        }
    }
}

sub show_usbfilter_dialog() {
    my %filter = &getsel_list_usbfilters;
    $gui{entryUSBFilterName}->set_text(IUSBDeviceFilter_getName($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterVendorID}->set_text(IUSBDeviceFilter_getVendorId($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterProductID}->set_text(IUSBDeviceFilter_getProductId($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterRevision}->set_text(IUSBDeviceFilter_getRevision($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterManufacturer}->set_text(IUSBDeviceFilter_getManufacturer($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterProduct}->set_text(IUSBDeviceFilter_getProduct($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterSerial}->set_text(IUSBDeviceFilter_getSerialNumber($filter{IUSBDeviceFilter}));
    $gui{entryUSBFilterPort}->set_text(IUSBDeviceFilter_getPort($filter{IUSBDeviceFilter}));
    my $remote = IUSBDeviceFilter_getRemote($filter{IUSBDeviceFilter});

    if ($remote eq 'yes') { $gui{comboboxUSBFilterRemote}->set_active(1); }
    elsif ($remote eq 'no') { $gui{comboboxUSBFilterRemote}->set_active(2); }
    else { $gui{comboboxUSBFilterRemote}->set_active(0); }

    my $response = $gui{dialogUSBFilter}->run;
    $gui{dialogUSBFilter}->hide;

    if ($response eq 'ok') {
        my $IUSBController = IMachine_getUSBController($EIMachineM);
        IUSBController_removeDeviceFilter($IUSBController, $filter{Position}); # Remove the original filter
        # Create the new filter based on the old
        my $newfilter = IUSBController_createDeviceFilter($IUSBController, $gui{entryUSBFilterName}->get_text());
        IUSBDeviceFilter_setActive($newfilter, $filter{Enabled});
        IUSBDeviceFilter_setVendorId($newfilter, $gui{entryUSBFilterVendorID}->get_text());
        IUSBDeviceFilter_setProductId($newfilter, $gui{entryUSBFilterProductID}->get_text());
        IUSBDeviceFilter_setRevision($newfilter, $gui{entryUSBFilterRevision}->get_text());
        IUSBDeviceFilter_setManufacturer($newfilter, $gui{entryUSBFilterManufacturer}->get_text());
        IUSBDeviceFilter_setProduct($newfilter, $gui{entryUSBFilterProduct}->get_text());
        IUSBDeviceFilter_setSerialNumber($newfilter, $gui{entryUSBFilterSerial}->get_text());
        IUSBDeviceFilter_setPort($newfilter, $gui{entryUSBFilterPort}->get_text());
        IUSBController_insertDeviceFilter($IUSBController, $filter{Position}, $newfilter);
        my $remote = $gui{comboboxUSBFilterRemote}->get_active();

        if ($remote == 1) { IUSBDeviceFilter_setRemote($newfilter, 'yes'); }
        elsif ($remote == 2) { IUSBDeviceFilter_setRemote($newfilter, 'no'); }
        else { IUSBDeviceFilter_setRemote($newfilter, ''); }

        &fill_list_usbfilters($IUSBController);
    }
}

sub show_createhd_dialog() {
    my $guestname = IMachine_getName($EIMachineM);
    $gui{entryCreateHDName}->set_text($guestname . int(rand(9999)));
    $gui{spinbuttonCreateHDSize}->set_range(8.00, int($hostspec{maxhdsize}/1048576));
    $gui{spinbuttonCreateHDSize}->set_value(8192.00);
    my $response = $gui{dialogCreateHD}->run;
    $gui{dialogCreateHD}->hide;
    my $diskname = $gui{entryCreateHDName}->get_text();
    $diskname =~ s/\.vdi$//;
    my $disksize = $gui{spinbuttonCreateHDSize}->get_value_as_int() * 1048576;

    if ($diskname and ($response eq 'ok')) {
        my $IMedium;
        my $location = &get_path_only(IMachine_getSettingsFilePath($EIMachineM));

        if ($gui{checkbuttonCreateHDDynamic}->get_active()) { $IMedium = &create_new_hd($diskname, $location, 'vdi', $EMediumVariant{Standard}, $disksize, $gui{dialogEdit}); }
        else { $IMedium = &create_new_hd($diskname, $location, 'vdi', $EMediumVariant{Fixed}, $disksize, $gui{dialogEdit}); }

        &editstor_attach_add(undef, $IMedium);
    }
}

sub show_edit_dialog() {
    &busy_window($gui{windowMain}, 0, 'watch');
    my %guest = &getsel_list_guest();
    my ($ISession, $IMachineM) = &get_mutable_session($guest{IMachine});

    if ($ISession) {
        &addrow_log("Retrieving guest settings for $guest{Name}...");
        $gui{dialogEdit}->set_title("Edit Settings - $guest{Name}");
        $EIMachineM = $IMachineM;
        $gui{comboboxEditGenOSFam}->signal_handler_block($signal{famedit});
        $gui{comboboxEditGenOSVer}->signal_handler_block($signal{veredit});
        $gui{comboboxEditAudioDriver}->signal_handler_block($signal{audiodrv});
        $gui{comboboxEditAudioCtr}->signal_handler_block($signal{audioctr});
        $gui{comboboxEditNetType1}->signal_handler_block($signal{netadaptype1});
        $gui{comboboxEditNetType2}->signal_handler_block($signal{netadaptype2});
        $gui{comboboxEditNetType3}->signal_handler_block($signal{netadaptype3});
        $gui{comboboxEditNetType4}->signal_handler_block($signal{netadaptype4});
        $gui{comboboxEditNetAttach1}->signal_handler_block($signal{netattach1});
        $gui{comboboxEditNetAttach2}->signal_handler_block($signal{netattach2});
        $gui{comboboxEditNetAttach3}->signal_handler_block($signal{netattach3});
        $gui{comboboxEditNetAttach4}->signal_handler_block($signal{netattach4});
        $gui{comboboxEditNetName1}->signal_handler_block($signal{netname1});
        $gui{comboboxEditNetName2}->signal_handler_block($signal{netname2});
        $gui{comboboxEditNetName3}->signal_handler_block($signal{netname3});
        $gui{comboboxEditNetName4}->signal_handler_block($signal{netname4});
        &clr_list($gui{liststoreEditGenOSFam}, $gui{liststoreEditGenOSVer}, $gui{liststoreEditAudioDriver},
                  $gui{liststoreEditAudioCtr}, $gui{liststoreEditNetAdapterType1}, $gui{liststoreEditNetAdapterType2},
                  $gui{liststoreEditNetAdapterType3}, $gui{liststoreEditNetAdapterType4}, $gui{liststoreEditNetAttachTo1},
                  $gui{liststoreEditNetAttachTo2}, $gui{liststoreEditNetAttachTo3}, $gui{liststoreEditNetAttachTo4},
                  $gui{liststoreEditNetName1}, $gui{liststoreEditNetName2}, $gui{liststoreEditNetName3},
                  $gui{liststoreEditNetName4}, $gui{liststoreEditSysBoot});
        # These widgets must start insensitive
        &sensitive_off($gui{buttonEditSysBootUp}, $gui{buttonEditSysBootDown});
        &setup_edit_dialog_general($guest{Name}, $guest{Osid}, $IMachineM);
        &setup_edit_dialog_system($IMachineM);
        &setup_edit_dialog_display($IMachineM);
        &setup_edit_dialog_storage($IMachineM);
        &setup_edit_dialog_audio($IMachineM);
        &setup_edit_dialog_network($IMachineM);
        &setup_edit_dialog_serial($IMachineM);
        &setup_edit_dialog_usb($IMachineM);
        &setup_edit_dialog_shared($IMachineM);
        $gui{comboboxEditGenOSFam}->signal_handler_unblock($signal{famedit});
        $gui{comboboxEditGenOSVer}->signal_handler_unblock($signal{veredit});
        $gui{comboboxEditAudioDriver}->signal_handler_unblock($signal{audiodrv});
        $gui{comboboxEditAudioCtr}->signal_handler_unblock($signal{audioctr});
        $gui{comboboxEditNetType1}->signal_handler_unblock($signal{netadaptype1});
        $gui{comboboxEditNetType2}->signal_handler_unblock($signal{netadaptype2});
        $gui{comboboxEditNetType3}->signal_handler_unblock($signal{netadaptype3});
        $gui{comboboxEditNetType4}->signal_handler_unblock($signal{netadaptype4});
        $gui{comboboxEditNetAttach1}->signal_handler_unblock($signal{netattach1});
        $gui{comboboxEditNetAttach2}->signal_handler_unblock($signal{netattach2});
        $gui{comboboxEditNetAttach3}->signal_handler_unblock($signal{netattach3});
        $gui{comboboxEditNetAttach4}->signal_handler_unblock($signal{netattach4});
        $gui{comboboxEditNetName1}->signal_handler_unblock($signal{netname1});
        $gui{comboboxEditNetName2}->signal_handler_unblock($signal{netname2});
        $gui{comboboxEditNetName3}->signal_handler_unblock($signal{netname3});
        $gui{comboboxEditNetName4}->signal_handler_unblock($signal{netname4});
        &addrow_log("Settings retrieved for $guest{Name}.");
        &busy_window($gui{windowMain}, 0);
        my $response = $gui{dialogEdit}->run;
        $gui{dialogEdit}->hide;

        if ($response eq 'ok') {
            IMachine_saveSettings($IMachineM);
            &fill_list_guest();
        }
        else { IMachine_discardSettings($IMachineM); }

        ISession_unlockMachine($ISession);
        $EIMachineM = undef;
        $gui{menuitemAttachFloppy} = undef; # These must be freed
        $gui{menuitemAttachDVD} = undef;
        $gui{menuitemAttachHD} = undef;
        $gui{menuAttachFloppy} = undef;
        $gui{menuAttachDVD} = undef;
        $gui{menuAttachHD} = undef;
        $gui{menuAttachAdd} = undef;
        $gui{menuUSB} = undef;
    }
    else { &show_err_msg('settings', $gui{messagedialogWarning}); }
}

sub setup_edit_dialog_general() {
    my ($Name, $Osid, $IMachine) = @_;
    my $IGuestOSType = IVirtualBox_getGuestOSType($gui{websn}, $Osid);
    $gui{entryEditGenName}->set_text($Name);

    foreach my $fam (sort(keys %osfamily)) {
        my $iter = &addrow_list($gui{liststoreEditGenOSFam}, 0, $osfamily{$fam}{description}, 1, $fam, 2, $osfamily{$fam}{icon});
        $gui{comboboxEditGenOSFam}->set_active_iter($iter) if ($fam eq $$IGuestOSType{familyId});
    }

    foreach my $ver (sort(@{ $osfamily{$$IGuestOSType{familyId}}{verids} })) {
        my $iter = &addrow_list($gui{liststoreEditGenOSVer}, 0, $osversion{$ver}{description}, 1, $ver, 2, $osversion{$ver}{icon});
        $gui{comboboxEditGenOSVer}->set_active_iter($iter) if ($ver eq $$IGuestOSType{id});
    }

    my $clipmode = IMachine_getClipboardMode($IMachine);

    if ($clipmode eq 'HostToGuest') { $gui{comboboxEditGenClip}->set_active(1); }
    elsif ($clipmode eq 'GuestToHost') { $gui{comboboxEditGenClip}->set_active(2); }
    elsif ($clipmode eq 'Bidirectional') { $gui{comboboxEditGenClip}->set_active(3); }
    else { $gui{comboboxEditGenClip}->set_active(0); }
}

sub setup_edit_dialog_system() {
    my ($IMachine) = @_;
    my $IBIOSSettings = IMachine_getBIOSSettings($IMachine);
    my $chipset = IMachine_getChipsetType($IMachine);
    my $pointer = IMachine_getPointingHidType($IMachine);

    if (IMachine_getFirmwareType($IMachine) =~ m/^EFI/) { $gui{checkbuttonEditSysEFI}->set_active(1); }
    else { $gui{checkbuttonEditSysEFI}->set_active(0); }

    $gui{spinbuttonEditSysMem}->set_range(4, $hostspec{memsize});
    $gui{spinbuttonEditSysMem}->set_value(IMachine_getMemorySize($IMachine));
    $gui{checkbuttonEditSysVTX}->set_active($ETruth{IMachine_getHWVirtExProperty($IMachine, 'Enabled')});
    $gui{checkbuttonEditSysNested}->set_active($ETruth{IMachine_getHWVirtExProperty($IMachine, 'NestedPaging')});
    $gui{hscaleEditSysProcessor}->set_range($hostspec{minguestcpu}, $hostspec{maxhostcpuon} + 1); # +1 works around GTK bug
    $gui{hscaleEditSysProcessor}->set_value(IMachine_getCPUCount($IMachine));
    $gui{checkbuttonEditSysAPIC}->set_active($ETruth{IBIOSSettings_getIOAPICEnabled($IBIOSSettings)});
    $gui{checkbuttonEditSysPAE}->set_active($ETruth{IMachine_getCPUProperty($IMachine, 'PAE')});
    $gui{checkbuttonEditSysUTC}->set_active($ETruth{IMachine_getRTCUseUTC($IMachine)});

    if ($chipset eq 'ICH9') { $gui{comboboxEditSysChipset}->set_active(1); }
    else { $gui{comboboxEditSysChipset}->set_active(0); }

    if ($pointer eq 'PS2Mouse') { $gui{comboboxEditSysPointing}->set_active(1); }
    elsif ($pointer eq 'USBMouse') { $gui{comboboxEditSysPointing}->set_active(2); }
    elsif ($pointer eq 'USBTablet') { $gui{comboboxEditSysPointing}->set_active(3); }
    elsif ($pointer eq 'ComboMouse') { $gui{comboboxEditSysPointing}->set_active(4); }
    else { $gui{comboboxEditSysPointing}->set_active(0); }

    # Default to maxbootpos+1 to mean 'not set in boot order' but this number needs to be higher than
    # true boot order numbers so the disabled devices appear at the end of the list.
    my %bootorder = (Floppy   => $hostspec{maxbootpos} + 1,
                     DVD      => $hostspec{maxbootpos} + 1,
                     HardDisk => $hostspec{maxbootpos} + 1,
                     Network  => $hostspec{maxbootpos} + 1);
    # Find boot order and set value in hash accordingly. Empty boot slots return 'Null' so skip them
    foreach (1..$hostspec{maxbootpos}) {
        my $bootdev = IMachine_getBootOrder($IMachine, $_);
        next if ($bootdev eq 'Null');
        $bootorder{$bootdev} = $_;
    }
    # Returns hash keys sorted by value (ie boot order). Disabled devices appear at end
    foreach my $dev (sort {$bootorder{$a} cmp $bootorder{$b}} keys %bootorder) {
        if ($bootorder{$dev} == $hostspec{maxbootpos} + 1) { &addrow_list($gui{liststoreEditSysBoot}, 0, 0, 1, $dev); }
        else { &addrow_list($gui{liststoreEditSysBoot}, 0, 1, 1, $dev); }
    }
}

sub setup_edit_dialog_display() {
    my ($IMachine) = @_;
    my $IVRDEServer = IMachine_getVRDEServer($IMachine);
    $gui{spinbuttonEditDispVidMem}->set_range($hostspec{minguestvram}, $hostspec{maxguestvram});
    $gui{spinbuttonEditDispVidMem}->set_value(IMachine_getVRAMSize($IMachine));
    $gui{spinbuttonEditDispMonitor}->set_range(1, $hostspec{maxmonitors});
    $gui{spinbuttonEditDispMonitor}->set_value(IMachine_getMonitorCount($IMachine));
    $gui{checkbuttonEditDisp3D}->set_active($ETruth{IMachine_getAccelerate3DEnabled($IMachine)});
    $gui{checkbuttonEditDisp2D}->set_active($ETruth{IMachine_getAccelerate2DVideoEnabled($IMachine)});
    $gui{checkbuttonEditDispServer}->set_active($ETruth{IVRDEServer_getEnabled($IVRDEServer)});
    $gui{entryEditDispPort}->set_text(IVRDEServer_getVRDEProperty($IVRDEServer, 'TCP/Ports'));
    $gui{entryEditDispAuthTime}->set_text(IVRDEServer_getAuthTimeout($IVRDEServer));
    $gui{checkbuttonEditDispMultiple}->set_active($ETruth{IVRDEServer_getAllowMultiConnection($IVRDEServer)});
    # Bit hacky to work around what appears to be a bug in VB 4.0.x
    my $dispqual = IVRDEServer_getVRDEProperty($IVRDEServer, 'VideoChannel/Quality');
    if (!$dispqual) { IVRDEServer_setVRDEProperty($IVRDEServer, 'VideoChannel/Quality', 75); }
    $gui{spinbuttonEditDispQuality}->set_value(int(IVRDEServer_getVRDEProperty($IVRDEServer, 'VideoChannel/Quality')));
    my $authtype = IVRDEServer_getAuthType($IVRDEServer);

    if ($authtype eq 'External') { $gui{comboboxDispAuthMeth}->set_active(1); }
    elsif ($authtype eq 'Guest') { $gui{comboboxDispAuthMeth}->set_active(2); }
    else { $gui{comboboxDispAuthMeth}->set_active(0); }
}

sub setup_edit_dialog_audio() {
    my ($IMachine) = @_;
    my $IAudioAdapter = IMachine_getAudioAdapter($IMachine);
    $gui{checkbuttonEditAudioEnable}->set_active($ETruth{IAudioAdapter_getEnabled($IAudioAdapter)});

    foreach my $driver (sort(keys %EAudioDriverType)) {
        if ($hostspec{os} =~ m/${EAudioDriverType{$driver}{os}}/ or $EAudioDriverType{$driver}{os} eq 'All') {
            my $iter = &addrow_list($gui{liststoreEditAudioDriver}, 0, $EAudioDriverType{$driver}{desc}, 1, $driver);
            $gui{comboboxEditAudioDriver}->set_active_iter($iter) if ($driver eq IAudioAdapter_getAudioDriver($IAudioAdapter));
        }
    }

    foreach my $ctr (sort(keys %EAudioControllerType)) {
        my $iter = &addrow_list($gui{liststoreEditAudioCtr}, 0, $EAudioControllerType{$ctr}, 1, $ctr);
        $gui{comboboxEditAudioCtr}->set_active_iter($iter) if ($ctr eq IAudioAdapter_getAudioController($IAudioAdapter));
    }
}

sub setup_edit_dialog_network() {
    my ($IMachine) = @_;
    my $IHost = IVirtualBox_getHost($gui{websn});

    foreach my $slot (1..4) {
        my $INetworkAdapter = IMachine_getNetworkAdapter($IMachine,($slot-1));
        my $NetAdapterType = INetworkAdapter_getAdapterType($INetworkAdapter);
        my $AttachType = INetworkAdapter_getAttachmentType($INetworkAdapter);
        my $hostinterface = INetworkAdapter_getHostInterface($INetworkAdapter);
        my @IHostNetworkInterface = IHost_getNetworkInterfaces($IHost);
        $gui{'checkbuttonEditNetEnable' . $slot}->set_active($ETruth{INetworkAdapter_getEnabled($INetworkAdapter)});
        $gui{'checkbuttonEditNetCable' . $slot}->set_active($ETruth{INetworkAdapter_getCableConnected($INetworkAdapter)});
        $gui{'entryEditNetMac' . $slot}->set_text(INetworkAdapter_getMACAddress($INetworkAdapter));
        # Set current adapter type for NICs 1-4
        foreach my $adaptertype (sort(keys %ENetworkAdapterType)) {
            my $iter = &addrow_list($gui{'liststoreEditNetAdapterType' . $slot},
                                    0,  $ENetworkAdapterType{$adaptertype},
                                    1, $adaptertype);
            $gui{'comboboxEditNetType' . $slot}->set_active_iter($iter) if ($adaptertype eq $NetAdapterType);
        }
        # Set current attachment type for NICs 1-4
        foreach my $attach (sort(keys %ENetworkAttachmentType)) {
            my $iter = &addrow_list($gui{'liststoreEditNetAttachTo' . $slot},
                                    0, $ENetworkAttachmentType{$attach},
                                    1, $attach);
            $gui{'comboboxEditNetAttach' . $slot}->set_active_iter($iter) if ($attach eq $AttachType);
        }

        if ($AttachType eq 'Bridged') {
            # Set current bridged network name for NICs 1-4, depending on attachment type
            foreach my $interface (@IHostNetworkInterface) {
                if (IHostNetworkInterface_getInterfaceType($interface) eq 'Bridged') {
                    my $name = IHostNetworkInterface_getName($interface);
                    my $iter = &addrow_list($gui{'liststoreEditNetName' . $slot}, 0, $name);
                    $gui{'comboboxEditNetName' . $slot}->set_active_iter($iter) if ($name eq $hostinterface);
                }
            }
            &hide_off($gui{'labelEditNetName' . $slot}, $gui{'comboboxEditNetName' . $slot});
            &hide_on($gui{'labelEditNetNameInt' . $slot}, $gui{'entryEditNetNameInt' . $slot});
        }
        elsif ($AttachType eq 'HostOnly') {
            # Set current hostonly network name for NICs 1-4, depending on attachment type
            foreach my $interface (@IHostNetworkInterface) {
                if (IHostNetworkInterface_getInterfaceType($interface) eq 'HostOnly') {
                    my $name = IHostNetworkInterface_getName($interface);
                    my $iter = &addrow_list($gui{'liststoreEditNetName' . $slot}, 0, $name);
                    $gui{'comboboxEditNetName' . $slot}->set_active_iter($iter) if ($name eq $hostinterface);
                }
            }
            &hide_off($gui{'labelEditNetName' . $slot}, $gui{'comboboxEditNetName' . $slot});
            &hide_on($gui{'labelEditNetNameInt' . $slot}, $gui{'entryEditNetNameInt' . $slot});
        }
        elsif ($AttachType eq 'Internal') {
            my $name = INetworkAdapter_getInternalNetwork($INetworkAdapter);
            $gui{'entryEditNetNameInt' . $slot}->set_text($name);
            &hide_on($gui{'labelEditNetName' . $slot}, $gui{'comboboxEditNetName' . $slot});
            &hide_off($gui{'labelEditNetNameInt' . $slot}, $gui{'entryEditNetNameInt' . $slot});
        }
        #elsif ($AttachType eq 'VDE') {
        #
        #}
        else {
            # All other networking types do not have name associated with them
            &hide_on($gui{'labelEditNetName' . $slot}, $gui{'comboboxEditNetName' . $slot},
                     $gui{'labelEditNetNameInt' . $slot}, $gui{'entryEditNetNameInt' . $slot});
        }
    }
}

sub setup_edit_dialog_serial() {
    my ($IMachine) = @_;

    foreach my $slot (1..2) {
        my $ISerialPort = IMachine_getSerialPort($IMachine, ($slot - 1));
        my $irq = ISerialPort_getIRQ($ISerialPort);
        my $ioport = sprintf('%X', ISerialPort_getIOBase($ISerialPort));
        my $mode = ISerialPort_getHostMode($ISerialPort);
        $gui{'checkbuttonEditSerialEnable' . $slot}->set_active($ETruth{ISerialPort_getEnabled($ISerialPort)});
        $gui{'checkbuttonEditSerialPipe' . $slot}->set_active($ETruth{ISerialPort_getServer($ISerialPort)});
        $gui{'entryEditSerialPath' . $slot}->set_text(ISerialPort_getPath($ISerialPort));
        $gui{'entryEditSerialIRQ' . $slot}->set_text($irq);
        $gui{'entryEditSerialIO' . $slot}->set_text($ioport);
        &sensitive_off($gui{'entryEditSerialIRQ' . $slot}, $gui{'entryEditSerialIO' . $slot});

        if ($irq == 4 and uc($ioport) eq '3F8') { $gui{'comboboxEditSerialPortNum' . $slot}->set_active(0); }
        elsif ($irq == 3 and uc($ioport) eq '2F8') { $gui{'comboboxEditSerialPortNum' . $slot}->set_active(1); }
        elsif ($irq == 4 and uc($ioport) eq '3E8') { $gui{'comboboxEditSerialPortNum' . $slot}->set_active(2); }
        elsif ($irq == 3 and uc($ioport) eq '2E8') { $gui{'comboboxEditSerialPortNum' . $slot}->set_active(3); }
        else {
            $gui{'comboboxEditSerialPortNum' . $slot}->set_active(4);
            &sensitive_on($gui{'entryEditSerialIRQ' . $slot}, $gui{'entryEditSerialIO' . $slot});
        }

        if ($mode eq 'HostPipe') { $gui{'comboboxEditSerialMode' . $slot}->set_active(1); }
        elsif ($mode eq 'HostDevice') { $gui{'comboboxEditSerialMode' . $slot}->set_active(2); }
        elsif ($mode eq 'RawFile') { $gui{'comboboxEditSerialMode' . $slot}->set_active(3); }
        else { $gui{'comboboxEditSerialMode' . $slot}->set_active(0); }
        $gui{'checkbuttonEditSerialPipe' . $slot}->set_active($ETruth{ISerialPort_getServer($ISerialPort)});
    }
}

sub setup_edit_dialog_usb() {
    my ($IMachine) = @_;
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    my $IHost = IVirtualBox_getHost($gui{websn});
    my @IHostUSBDevices = IHost_getUSBDevices($IHost);
    $gui{checkbuttonEditUSBEnable}->set_active($ETruth{IUSBController_getEnabled($IUSBController)});
    $gui{checkbuttonEditUSBEHCI}->set_active($ETruth{IUSBController_getEnabledEhci($IUSBController)});
    &fill_list_usbfilters($IUSBController);
    $gui{menuUSB} = Gtk2::Menu->new();

    foreach my $usb (@IHostUSBDevices) {
        my $label = &make_usb_label(IUSBDevice_getManufacturer($usb),
                                    IUSBDevice_getProduct($usb),
                                    sprintf('%04x', IUSBDevice_getRevision($usb)));

        my $item = Gtk2::MenuItem->new_with_label($label);
        $gui{menuUSB}->append($item);
        $item->show();
        my $usbid = IUSBDevice_getId($usb);
        $item->signal_connect(activate => \&add_usbfilter, $usbid);
    }
}

sub setup_edit_dialog_shared() {
    my ($IMachine) = @_;
    &fill_list_editshared($IMachine);
}

sub setup_edit_dialog_storage() {
    my ($IMachine) = @_;
    &fill_list_editstorage($IMachine);
    $gui{menuAttachAdd} = Gtk2::Menu->new();
    $gui{menuAttachHD} = Gtk2::Menu->new();
    $gui{menuAttachDVD} = Gtk2::Menu->new();
    $gui{menuAttachFloppy} = Gtk2::Menu->new();
    $gui{menuitemAttachHD} = Gtk2::MenuItem->new_with_label('Hard Disks');
    $gui{menuitemAttachDVD} = Gtk2::MenuItem->new_with_label('CDs/DVDs');
    $gui{menuitemAttachFloppy} = Gtk2::MenuItem->new_with_label('Floppy Disks');
    $gui{menuitemAttachHD}->set_submenu($gui{menuAttachHD});
    $gui{menuitemAttachDVD}->set_submenu($gui{menuAttachDVD});
    $gui{menuitemAttachFloppy}->set_submenu($gui{menuAttachFloppy});
    $gui{menuitemAttachHD}->show();
    $gui{menuitemAttachDVD}->show();
    $gui{menuitemAttachFloppy}->show();
    $gui{menuAttachAdd}->append($gui{menuitemAttachHD});
    $gui{menuAttachAdd}->append($gui{menuitemAttachDVD});
    $gui{menuAttachAdd}->append($gui{menuitemAttachFloppy});
    my $newhditem = Gtk2::MenuItem->new_with_label('Create New HardDisk');
    $gui{menuAttachHD}->append($newhditem);
    $newhditem->show();
    $newhditem->signal_connect(activate => \&show_createhd_dialog);
    my $sep = Gtk2::SeparatorMenuItem->new();
    $gui{menuAttachHD}->append($sep);
    $sep->show();

    my %IMediumHD = &get_all_media('HardDisk');
    my %IMediumDVD = &get_all_media('DVD');
    my %IMediumFloppy = &get_all_media('Floppy');

    foreach my $medium (sort { lc($a) cmp lc($b) } (keys %IMediumHD)) {
        my $item = Gtk2::MenuItem->new_with_label($medium);
        $gui{menuAttachHD}->append($item);
        $item->show();
        $item->signal_connect(activate => \&editstor_attach_add, $IMediumHD{$medium});
    }

    foreach my $medium (sort { lc($a) cmp lc($b) } (keys %IMediumDVD)) {
        my $item = Gtk2::MenuItem->new_with_label($medium);
        $gui{menuAttachDVD}->append($item);
        $item->show();
        $item->signal_connect(activate => \&editstor_attach_add, $IMediumDVD{$medium});
    }

    foreach my $medium (sort { lc($a) cmp lc($b) } (keys %IMediumFloppy)) {
        my $item = Gtk2::MenuItem->new_with_label($medium);
        $gui{menuAttachFloppy}->append($item);
        $item->show();
        $item->signal_connect(activate => \&editstor_attach_add, $IMediumFloppy{$medium});
    }
}

sub show_attach_menu() {
    my ($widget, $event) = @_;
    $gui{menuAttachAdd}->popup(undef, undef, undef, undef, 0, $event->time) if ($event->button == 1);
    return 0;
}

sub show_usb_menu() {
    my ($widget, $event) = @_;
    $gui{menuUSB}->popup(undef, undef, undef, undef, 0, $event->time) if ($event->button == 1);
    return 0;
}

sub show_ctr_menu() {
    my ($widget, $event) = @_; #$event->time
    $gui{menuCtrAdd}->popup(undef, undef, undef, undef, 0, $event->time) if ($event->button == 1);
    return 0;
}

sub editgen_name() {
    my $name = $gui{entryEditGenName}->get_text();
    IMachine_setName($EIMachineM, $name) if ($name);
}

sub editgen_osfam() {
    my ($combofam, $combover) = @_;
    my $fam = &getsel_combo($combofam, 1);
    $combofam->signal_handler_block($signal{famedit}); # Block to avoid signal emission when changing
    $combover->signal_handler_block($signal{veredit});
    &clr_list($gui{liststoreEditGenOSVer});

    foreach my $ver (sort(@{ $osfamily{$fam}{verids} })) {
        my $iter = &addrow_list($gui{liststoreEditGenOSVer}, 0, $osversion{$ver}{description}, 1, $ver, 2, $osversion{$ver}{icon});
        $combover->set_active_iter($iter) if ($ver eq 'WindowsXP' | $ver eq 'Ubuntu' | $ver eq 'Solaris');
    }

    $combover->set_active(0) if ($combover->get_active() == -1);
    $combofam->signal_handler_unblock($signal{famedit});
    $combover->signal_handler_unblock($signal{veredit});
    $combover->signal_emit('changed'); # Force update of other fields based on OS
}

sub editgen_osver() {
    my ($combover) = @_;
    my $ver = &getsel_combo($combover, 1);
    IMachine_setOSTypeId($EIMachineM, $ver);
}

sub editgen_clip() { IMachine_setClipboardMode($EIMachineM, &getsel_combo($gui{comboboxEditGenClip}, 0)); }

sub editsys_mem() {
    my ($widget, $focus, $adjust) = @_;
    IMachine_setMemorySize($EIMachineM, int($adjust->get_value()));
    return 0; # Must return this value for the signal used.
}

sub editsys_apic() {
    my $IBIOSSettings = IMachine_getBIOSSettings($EIMachineM);
    IBIOSSettings_setIOAPICEnabled($IBIOSSettings, $gui{checkbuttonEditSysAPIC}->get_active());
}

sub editsys_efi() {
    if ($gui{checkbuttonEditSysEFI}->get_active() == 1) { IMachine_setFirmwareType($EIMachineM, 'EFI'); }
    else { IMachine_setFirmwareType($EIMachineM, 'BIOS'); }
}

sub editsys_processors() {
    my ($widget, $focus, $adjust) = @_;
    IMachine_setCPUCount($EIMachineM, int($adjust->get_value()));
    return 0; # Must return this value for the signal used.
}

sub editsys_pae() { IMachine_setCPUProperty($EIMachineM, 'PAE', $gui{checkbuttonEditSysPAE}->get_active()); }

sub editsys_vtx() { IMachine_setHWVirtExProperty($EIMachineM, 'Enabled', $gui{checkbuttonEditSysVTX}->get_active()); }

sub editsys_utc() { IMachine_setRTCUseUTC($EIMachineM, $gui{checkbuttonEditSysUTC}->get_active()); }

sub editsys_pointer() { IMachine_setPointingHidType($EIMachineM, &getsel_combo($gui{comboboxEditSysPointing}, 1)); }

sub editsys_chipset() { IMachine_setChipsetType($EIMachineM, &getsel_combo($gui{comboboxEditSysChipset}, 0)); }

sub editsys_nested() { IMachine_setHWVirtExProperty($EIMachineM, 'NestedPaging', $gui{checkbuttonEditSysNested}->get_active()); }

sub editsys_boot_up() {
    my ($model, $iter) = $gui{treeviewEditSysBoot}->get_selection->get_selected;
    my $path = $model->get_path($iter);
    $path->prev;
    my $previter = $model->get_iter($path);
    $model->move_before($iter, $previter);
}

sub editsys_boot_down() {
    my ($model, $iter) = $gui{treeviewEditSysBoot}->get_selection->get_selected;
    my $nextiter = $model->iter_next($iter);
    $model->move_after($iter, $nextiter) if ($nextiter);
}

sub editsys_bootorder() {
    my $model = $gui{treeviewEditSysBoot}->get_model();
    my $iter = $model->get_iter_first();
    my $i = 1;

    while ($iter) {
        my $dev = $model->get($iter,1);
        $dev = 'Null' if ($model->get($iter,0) == 0);
        IMachine_setBootOrder($EIMachineM, $i, $dev);
        $iter = $model->iter_next($iter);
        $i++;
    }
}

sub editsys_boot_selected() { &sensitive_on($gui{buttonEditSysBootDown}, $gui{buttonEditSysBootUp}); }

sub editsys_boot_toggle() {
    my ($widget, $path_str, $model) = @_;
    my $iter = $model->get_iter(Gtk2::TreePath->new_from_string($path_str));
    my $val = $model->get($iter, 0);
    $model->set ($iter, 0, !$val); # Always set the opposite of val to act as a toggle
}

sub editdisp_vidmem() {
    my ($widget, $focus, $adjust) = @_;
    IMachine_setVRAMSize($EIMachineM, int($adjust->get_value()));
    return 0; # Must return this value for the signal used.
}

sub editdisp_monitors() {
    my ($widget, $focus, $adjust) = @_;
    IMachine_setMonitorCount($EIMachineM, int($adjust->get_value()));
    return 0; # Must return this value for the signal used.
}

sub editdisp_2D() { IMachine_setAccelerate2DVideoEnabled($EIMachineM, $gui{checkbuttonEditDisp2D}->get_active()); }

sub editdisp_3D() { IMachine_setAccelerate3DEnabled($EIMachineM, $gui{checkbuttonEditDisp3D}->get_active()); }

sub editdisp_RDP() {
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setEnabled($IVRDEServer, $gui{checkbuttonEditDispServer}->get_active());
}

sub editdisp_RDPTime() {
    my $authtime = int($gui{entryEditDispAuthTime}->get_text());
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setAuthTimeout($IVRDEServer, $authtime) if ($authtime);
}

sub editdisp_RDPPort() {
    my $ports = $gui{entryEditDispPort}->get_text();
    # Ideally some additional validation would be needed here
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setVRDEProperty($IVRDEServer, 'TCP/Ports', $ports) if ($ports);
}

sub editdisp_RDPAuth() {
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setAuthType($IVRDEServer, &getsel_combo($gui{comboboxDispAuthMeth}, 1));
}

sub editdisp_RDPMulti() {
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setAllowMultiConnection($IVRDEServer, $gui{checkbuttonEditDispMultiple}->get_active());
}

sub editdisp_quality() {
    my ($widget, $focus, $adjust) = @_;
    my $IVRDEServer = IMachine_getVRDEServer($EIMachineM);
    IVRDEServer_setVRDEProperty($IVRDEServer, 'VideoChannel/Quality', int($adjust->get_value()));
    return 0; # Must return this value for the signal used.
}

sub editstor_ctr_add() {
    my ($widget) = @_;
    my $bus = 'Floppy'; # Assume floppy unless set otherwise

    if ($widget eq $gui{menuitemCtrAddIDE}) { $bus = 'IDE'; }
    elsif ($widget eq $gui{menuitemCtrAddSCSI}) { $bus = 'SCSI'; }
    elsif ($widget eq $gui{menuitemCtrAddSATA}) { $bus = 'SATA'; }
    elsif ($widget eq $gui{menuitemCtrAddSAS}) { $bus = 'SAS'; }

    my @IStorageController = IMachine_getStorageControllers($EIMachineM);
    my $exists = 0;

    foreach my $ctr (@IStorageController) { $exists = 1 if (IStorageController_getBus($ctr) eq $bus) }

    if (!$exists) {
        IMachine_addStorageController($EIMachineM, "$bus Controller", $bus);
        &fill_list_editstorage($EIMachineM);
    }
    elsif ($exists) { &show_err_msg('ctrallocated', $gui{messagedialogError}); }
}

sub editstor_attach_add() {
    my ($widget, $IMedium) = @_;
    my %storitem = &getsel_list_editstorage();

    # Check if the item is a controller or DVD/Floppy device
    if ($storitem{Type} eq 'DVD') {
        IMachine_mountMedium($EIMachineM, $storitem{Controllernameformedia}, $storitem{Port}, $storitem{Devnum}, $IMedium);
    }
    elsif ($storitem{Type} eq 'Floppy') {
        IMachine_mountMedium($EIMachineM, $storitem{Controllernameformedia}, $storitem{Port}, $storitem{Devnum}, $IMedium);
    }
    else {
        my $mtype = IMedium_getDeviceType($IMedium);
        my ($freedev, $freeport) = &get_free_deviceport($EIMachineM, $storitem{IObject});
        my @IMediumAttachment = IMachine_getMediumAttachmentsOfController($EIMachineM, $storitem{Name});
        my $attached = 0;

        # Check for an empty Floppy/DVD first and try an use that (if medium appropriate)
        if ($mtype eq 'DVD') {
            foreach my $attach (@IMediumAttachment) {
                next if ($$attach{medium}); # We ignore if it already has a medium
                next if ($$attach{type} ne 'DVD'); # Only interested in DVD devices
                IMachine_mountMedium($EIMachineM, $storitem{Name}, $$attach{port}, $$attach{device}, $IMedium);
                $attached = 1;
            }
        }
        elsif ($mtype eq 'Floppy') {
            foreach my $attach (@IMediumAttachment) {
                next if ($$attach{medium}); # We ignore if it already has a medium
                next if ($$attach{type} ne 'Floppy'); # Only interested in DVD devices
                IMachine_mountMedium($EIMachineM, $storitem{Name}, $$attach{port}, $$attach{device}, $IMedium);
                $attached = 1;
            }

        }

        # For non removable media or if no empty Floppy/DVD, then add new attachment
        if ($attached == 0) {
            if ($freedev ne -1) {
                &create_sas_sata_port($storitem{IObject}); # Harmless if not SAS/SATA controller
                IMachine_attachDevice($EIMachineM, $storitem{Name}, $freeport, $freedev, $mtype, $IMedium);
                $attached = 1
            }
        }

        # If medium wasn't attached, controller must be full
        if (!$attached) { &show_err_msg('ctrfull', $gui{messagedialogError}); }
    }

    &fill_list_editstorage($EIMachineM);
}

sub editstor_attach_rem() {
    my %storitem = &getsel_list_editstorage();
    # Unmount removable media, otherwise remove device for everything.
    if ((($storitem{Type} eq 'Floppy') or ($storitem{Type} eq 'DVD')) and ($storitem{IObject} ne '<empty>')) {
        IMachine_mountMedium($EIMachineM, $storitem{Controllernameformedia}, $storitem{Port}, $storitem{Devnum}, '');
    }
    else { IMachine_detachDevice($EIMachineM, $storitem{Controllernameformedia}, $storitem{Port}, $storitem{Devnum}); }

    &fill_list_editstorage($EIMachineM);
}

sub editstor_ctr_rem() {
    my %storitem = &getsel_list_editstorage();
    my @IMediumAttachments = IMachine_getMediumAttachmentsOfController($EIMachineM, $storitem{Name});

    if (@IMediumAttachments) { &show_err_msg('ctrinuse', $gui{messagedialogWarning}); }
    else { IMachine_removeStorageController($EIMachineM, $storitem{Name}); }

    &fill_list_editstorage($EIMachineM);
}

sub editstor_ctrtype_fill() {
    my ($ctype, $IStorCtr) = @_;
    $gui{comboboxEditStorCtrType}->signal_handler_block($signal{stortype});
    &clr_list($gui{liststoreEditStorCtrType});
    my $cvariant = IStorageController_getControllerType($IStorCtr);

    if ($ctype eq 'IDE Controller') {
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'PIIX3');
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'PIIX4');
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'ICH6');
    }
    elsif ($ctype eq 'SATA Controller') {
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'IntelAhci');
    }
    elsif ($ctype eq 'SAS Controller') {
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'LsiLogicSas');
    }
    elsif ($ctype eq 'SCSI Controller') {
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'LsiLogic');
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'BusLogic');
    }
    elsif ($ctype eq 'Floppy Controller') {
        &addrow_list($gui{liststoreEditStorCtrType}, 0, 'I82078');
    }

    if ($cvariant eq 'ICH6') { $gui{comboboxEditStorCtrType}->set_active(2); }
    elsif ($cvariant eq 'PIIX4' || $cvariant eq 'BusLogic') { $gui{comboboxEditStorCtrType}->set_active(1); }
    else { $gui{comboboxEditStorCtrType}->set_active(0); }

    $gui{checkbuttonEditStorCache}->set_active($ETruth{IStorageController_getUseHostIOCache($IStorCtr)});
    $gui{comboboxEditStorCtrType}->signal_handler_unblock($signal{stortype});
}

sub editstor_ctrtype() {
    my %storitem = &getsel_list_editstorage();
    IStorageController_setControllerType($storitem{IObject}, &getsel_combo($gui{comboboxEditStorCtrType}, 0));
    &fill_list_editstorage($EIMachineM);
}

# Set/Clear the host I/O cache for the controller
sub editstor_ctrcache() {
    my %storitem = &getsel_list_editstorage();
    IStorageController_setUseHostIOCache($storitem{IObject}, $gui{checkbuttonEditStorCache}->get_active());
}

# Enable/Disable the audio controller
sub editaudio() {
    my $IAudioAdapter = IMachine_getAudioAdapter($EIMachineM);
    IAudioAdapter_setEnabled($IAudioAdapter, $gui{checkbuttonEditAudioEnable}->get_active());
}

sub editaudio_ctr() {
    my $IAudioAdapter = IMachine_getAudioAdapter($EIMachineM);
    my $controller = &getsel_combo($gui{comboboxEditAudioCtr}, 1);
    IAudioAdapter_setAudioController($IAudioAdapter, $controller);
}

sub editaudio_driver() {
    my $IAudioAdapter = IMachine_getAudioAdapter($EIMachineM);
    my $driver = &getsel_combo($gui{comboboxEditAudioDriver}, 1);
    IAudioAdapter_setAudioDriver($IAudioAdapter, $driver);
}

sub editnet_adapter() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    INetworkAdapter_setEnabled($INetworkAdapter, $widget->get_active());
}

sub editnet_cable() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    INetworkAdapter_setCableConnected($INetworkAdapter, $widget->get_active());
}

sub editnet_mac() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    my $mac = $widget->get_text();
    INetworkAdapter_setMACAddress($INetworkAdapter, $mac) if (length($mac) == 12);
}

sub editnet_adapter_type() {
    my ($widget, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    my $type = &getsel_combo($widget, 1);
    INetworkAdapter_setAdapterType($INetworkAdapter, $type);
}

sub editnet_attach() {
    my ($widget, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    $gui{'comboboxEditNetName' . $num}->signal_handler_block($signal{'netname' . $num});
    my $IHost = IVirtualBox_getHost($gui{websn});
    my $AttachType = &getsel_combo($widget, 1);
    &clr_list($gui{'liststoreEditNetName' . $num});

    if ($AttachType eq 'Bridged') {
        # Set current bridged network name for NICs 1-4, depending on attachment type
        my @IHostNetworkInterface = IHost_getNetworkInterfaces($IHost);
        foreach my $interface (@IHostNetworkInterface) {
            if (IHostNetworkInterface_getInterfaceType($interface) eq 'Bridged') {
                my $name = IHostNetworkInterface_getName($interface);
                my $iter = &addrow_list($gui{'liststoreEditNetName' . $num}, 0, $name);
            }
        }
        INetworkAdapter_attachToBridgedInterface($INetworkAdapter);
        &hide_off($gui{'labelEditNetName' . $num}, $gui{'comboboxEditNetName' . $num});
        &hide_on($gui{'labelEditNetNameInt' . $num}, $gui{'entryEditNetNameInt' . $num});
    }
    elsif ($AttachType eq 'HostOnly') {
        # Set current hostonly network name for NICs 1-4, depending on attachment type
        my @IHostNetworkInterface = IHost_getNetworkInterfaces($IHost);
        foreach my $interface (@IHostNetworkInterface) {
            if (IHostNetworkInterface_getInterfaceType($interface) eq 'HostOnly') {
                my $name = IHostNetworkInterface_getName($interface);
                my $iter = &addrow_list($gui{'liststoreEditNetName' . $num}, 0, $name);
            }
        }
        INetworkAdapter_attachToHostOnlyInterface($INetworkAdapter);
        &hide_off($gui{'labelEditNetName' . $num}, $gui{'comboboxEditNetName' . $num});
        &hide_on($gui{'labelEditNetNameInt' . $num}, $gui{'entryEditNetNameInt' . $num});
    }
    elsif ($AttachType eq 'Internal') {
        my $name = INetworkAdapter_getInternalNetwork($INetworkAdapter);
        $gui{'entryEditNetNameInt' . $num}->set_text($name);
        INetworkAdapter_attachToInternalNetwork($INetworkAdapter);
        &hide_on($gui{'labelEditNetName' . $num}, $gui{'comboboxEditNetName' . $num});
        &hide_off($gui{'labelEditNetNameInt' . $num}, $gui{'entryEditNetNameInt' . $num});
    }
    elsif ($AttachType eq 'NAT') {
        INetworkAdapter_attachToNAT($INetworkAdapter);
        &hide_on($gui{'labelEditNetName' . $num}, $gui{'comboboxEditNetName' . $num},
                 $gui{'labelEditNetNameInt' . $num}, $gui{'entryEditNetNameInt' . $num});
    }
    else {
        # Assume detach as we either don't support it yet, or it really is detach
        INetworkAdapter_detach($INetworkAdapter);
        &hide_on($gui{'labelEditNetName' . $num}, $gui{'comboboxEditNetName' . $num},
                 $gui{'labelEditNetNameInt' . $num}, $gui{'entryEditNetNameInt' . $num});
    }

    $gui{'comboboxEditNetName' . $num}->signal_handler_unblock($signal{'netname' . $num});
    $gui{'comboboxEditNetName' . $num}->set_active(0); # This will call editnet_name()
}

sub editnet_name() {
    my ($widget, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    my $AttachType = &getsel_combo($gui{'comboboxEditNetAttach' . $num}, 1);
    if ($AttachType eq 'Bridged' | $AttachType eq 'HostOnly') {
        INetworkAdapter_setHostInterface($INetworkAdapter, $gui{'comboboxEditNetName' . $num}->get_active_text());
    }
}

sub editnet_name_internal() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($INetworkAdapter, $num) = &callout_getnetadapter($checkbutton);
    my $name = $gui{'entryEditNetNameInt' . $num}->get_text();
    INetworkAdapter_setInternalNetwork($INetworkAdapter, $name) if ($name);
}

sub callout_getnetadapter() {
    my ($checkbutton) = @_;
    my $slot = 0;
    if ($checkbutton eq $gui{checkbuttonEditNetEnable1}) { $slot = 0; }
    elsif ($checkbutton eq $gui{checkbuttonEditNetEnable2}) { $slot = 1; }
    elsif ($checkbutton eq $gui{checkbuttonEditNetEnable3}) { $slot = 2; }
    elsif ($checkbutton eq $gui{checkbuttonEditNetEnable4}) { $slot = 3; }
    my $INetworkAdapter = IMachine_getNetworkAdapter($EIMachineM, $slot);
    return $INetworkAdapter, $slot+1;
}

sub callout_getserial() {
    my ($checkbutton) = @_;
    my $slot = 0;
    if ($checkbutton eq $gui{checkbuttonEditSerialEnable1}) { $slot = 0; }
    elsif ($checkbutton eq $gui{checkbuttonEditSerialEnable2}) { $slot = 1; }
    my $ISerialPort = IMachine_getSerialPort($EIMachineM, $slot);
    return $ISerialPort, $slot+1;
}

sub editserial() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($ISerialPort, $num) = &callout_getserial($checkbutton);
    ISerialPort_setEnabled($ISerialPort, $widget->get_active());
}

sub editserial_irq() {
    my ($widget, $focus, $checkbutton) = @_;
    my $irq = int($widget->get_text());
    $irq = 255 if ($irq > 255);
    $irq = 15 if ($irq > 15 and !$gui{checkbuttonEditSysAPIC}->get_active());
    my ($ISerialPort, $num) = &callout_getserial($checkbutton);
    ISerialPort_setIRQ($ISerialPort, $irq);
}

sub editserial_ioport() {
    my ($widget, $focus, $checkbutton) = @_;
    my $ioport = $widget->get_text();
    $ioport = 'FFFF' if (hex($ioport) > 65535);

    if ($ioport) {
        my ($ISerialPort, $num) = &callout_getserial($checkbutton);
        ISerialPort_setIOBase($ISerialPort, hex($ioport));
    }
}

sub editserial_portmode() {
    my ($widget, $checkbutton) = @_;
    my ($ISerialPort, $num) = &callout_getserial($checkbutton);
    ISerialPort_setHostMode($ISerialPort, &getsel_combo($widget, 0));
}

sub editserial_createpipe() {
    my ($widget, $focus, $checkbutton) = @_;
    my ($ISerialPort, $num) = &callout_getserial($checkbutton);
    ISerialPort_setServer($ISerialPort, $widget->get_active());
}

sub editserial_portpath() {
    my ($widget, $focus, $checkbutton) = @_;
    my $path = $widget->get_text();
    if ($path) {
        my ($ISerialPort, $num) = &callout_getserial($checkbutton);
        ISerialPort_setPath($ISerialPort, $path);
    }
}

sub editserial_portnum() {
    my ($widget, $checkbutton) = @_;
    my $portnum = &getsel_combo($widget, 0);
    my ($ISerialPort, $num) = &callout_getserial($checkbutton);

    if ($portnum eq 'COM1') {
        $gui{'entryEditSerialIRQ' . $num}->set_text('4');
        $gui{'entryEditSerialIO' . $num}->set_text('3F8');
    }
    elsif ($portnum eq 'COM2') {
        $gui{'entryEditSerialIRQ' . $num}->set_text('3');
        $gui{'entryEditSerialIO' . $num}->set_text('2F8');
    }
    elsif ($portnum eq 'COM3') {
        $gui{'entryEditSerialIRQ' . $num}->set_text('4');
        $gui{'entryEditSerialIO' . $num}->set_text('3E8');
    }
    elsif ($portnum eq 'COM4') {
        $gui{'entryEditSerialIRQ' . $num}->set_text('3');
        $gui{'entryEditSerialIO' . $num}->set_text('2E8');
    }

    if ($portnum ne 'Custom') {
        &editserial_irq($gui{'entryEditSerialIRQ' . $num}, 0, $checkbutton);
        &editserial_ioport($gui{'entryEditSerialIO' . $num}, 0, $checkbutton);
        &sensitive_off($gui{'entryEditSerialIRQ' . $num}, $gui{'entryEditSerialIO' . $num});
    }
    else { &sensitive_on($gui{'entryEditSerialIRQ' . $num}, $gui{'entryEditSerialIO' . $num}); }
}

sub editusb() {
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    IUSBController_setEnabled($IUSBController, $gui{checkbuttonEditUSBEnable}->get_active());
}

sub editusb_ehci() {
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    IUSBController_setEnabledEhci($IUSBController, $gui{checkbuttonEditUSBEHCI}->get_active());
}

sub add_usbfilter_zero() {
    my %filter = &getsel_list_usbfilters();
    my $pos = 0;

    # Determine position for new filter, based on whether one is selected or not
    $pos = $filter{Position} + 1 if ($filter{Position});
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    my $IUSBDeviceFilter = IUSBController_createDeviceFilter($IUSBController, "New Filter" . int(rand(9999)));
    IUSBDeviceFilter_setActive($IUSBDeviceFilter, 1);
    IUSBController_insertDeviceFilter($IUSBController, $pos, $IUSBDeviceFilter);
    &fill_list_usbfilters($IUSBController);
}

sub add_usbfilter() {
    my ($widget, $usbid) = @_;
    my %filter = &getsel_list_usbfilters();
    my $pos = 0;
    # Determine position for new filter, based on whether one is selected or not
    $pos = $filter{Position} + 1 if ($filter{Position});
    my $IHost = IVirtualBox_getHost($gui{websn});
    my $IHostUSBDevice = IHost_findUSBDeviceById($IHost, $usbid);
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    my %usbdevice = (vendorId     => sprintf('%04X', IUSBDevice_getVendorId($IHostUSBDevice)),
                     productId    => sprintf('%04x', IUSBDevice_getProductId($IHostUSBDevice)),
                     revision     => sprintf('%04x', IUSBDevice_getRevision($IHostUSBDevice)),
                     manufacturer => IUSBDevice_getManufacturer($IHostUSBDevice),
                     product      => IUSBDevice_getProduct($IHostUSBDevice),
                     serial       => IUSBDevice_getSerialNumber($IHostUSBDevice));

    my $label = &make_usb_label($usbdevice{manufacturer}, $usbdevice{product}, $usbdevice{revision});
    my $IUSBDeviceFilter = IUSBController_createDeviceFilter($IUSBController, $label);
    IUSBDeviceFilter_setActive($IUSBDeviceFilter, 1);
    IUSBDeviceFilter_setVendorId($IUSBDeviceFilter, $usbdevice{vendorId});
    IUSBDeviceFilter_setProductId($IUSBDeviceFilter, $usbdevice{productId});
    IUSBDeviceFilter_setRevision($IUSBDeviceFilter, $usbdevice{revision});
    IUSBDeviceFilter_setManufacturer($IUSBDeviceFilter, $usbdevice{manufacturer});
    IUSBDeviceFilter_setProduct($IUSBDeviceFilter, $usbdevice{product});
    IUSBDeviceFilter_setSerialNumber($IUSBDeviceFilter, $usbdevice{serial});
    IUSBController_insertDeviceFilter($IUSBController, $pos, $IUSBDeviceFilter);
    &fill_list_usbfilters($IUSBController);
    return 0;
}

sub make_usb_label() {
    my ($manu, $prod, $rev) = @_;
    my $label;
    $label = "$manu " if ($manu);
    $label .= "$prod " if ($prod);
    $label .= "[$rev]" if ($rev);
    return $label;
}

sub remove_usbfilter() {
    my %filter = &getsel_list_usbfilters();
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    IUSBController_removeDeviceFilter($IUSBController, $filter{Position});
    &fill_list_usbfilters($IUSBController);
}

sub move_usbfilter() {
    my ($widget) = @_;
    my $pos = 0;
    my %filter = &getsel_list_usbfilters();

    if ($widget eq $gui{buttonEditUSBUp} and $filter{Position} > 0) { $pos = -1; }
    elsif ($widget eq $gui{buttonEditUSBDown}) { $pos = 1; }

    my $IUSBController = IMachine_getUSBController($EIMachineM);
    my $IUSBDeviceFilter = IUSBController_removeDeviceFilter($IUSBController, $filter{Position});
    IUSBController_insertDeviceFilter($IUSBController, $filter{Position} + $pos, $IUSBDeviceFilter);
    &fill_list_usbfilters($IUSBController);
}

# Can't use getsel_list_usbfilters in here due to the way the signals are propagated
sub toggle_usbfilter() {
    my ($widget, $path_str, $model) = @_;
    my $IUSBController = IMachine_getUSBController($EIMachineM);
    my $iter = $model->get_iter(Gtk2::TreePath->new_from_string($path_str));
    my $val = $model->get($iter, 0);
    my $IUSBDeviceFilter = $model->get($iter, 1);
    IUSBDeviceFilter_setActive($IUSBDeviceFilter, !$val); # Always set to the opposite
    &fill_list_usbfilters($IUSBController);
}

sub remove_shared() {
    my %share = &getsel_list_editshared();
    IMachine_removeSharedFolder($EIMachineM, $share{Name});
    &fill_list_editshared($EIMachineM);
}

1;