mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
Add basic SmartCardDevice support
This patch allows to add and list smartcard devices in host or passthrough & spicevmc mode. It doesn't provide all the various smartcard combination options, but it's good enough for Spice usage. (crobinso: various small tweaks)
This commit is contained in:
parent
cfbc5e58f5
commit
9c600597c8
@ -24,8 +24,9 @@ import traceback
|
|||||||
import gtk
|
import gtk
|
||||||
|
|
||||||
import virtinst
|
import virtinst
|
||||||
from virtinst import (VirtualCharDevice, VirtualDevice, VirtualVideoDevice,
|
from virtinst import (VirtualCharDevice, VirtualDevice,
|
||||||
VirtualWatchdog, VirtualFilesystem)
|
VirtualVideoDevice, VirtualWatchdog,
|
||||||
|
VirtualFilesystem, VirtualSmartCardDevice)
|
||||||
|
|
||||||
import virtManager.util as util
|
import virtManager.util as util
|
||||||
import virtManager.uihelpers as uihelpers
|
import virtManager.uihelpers as uihelpers
|
||||||
@ -45,6 +46,7 @@ PAGE_CHAR = 7
|
|||||||
PAGE_VIDEO = 8
|
PAGE_VIDEO = 8
|
||||||
PAGE_WATCHDOG = 9
|
PAGE_WATCHDOG = 9
|
||||||
PAGE_FILESYSTEM = 10
|
PAGE_FILESYSTEM = 10
|
||||||
|
PAGE_SMARTCARD = 11
|
||||||
|
|
||||||
char_widget_mappings = {
|
char_widget_mappings = {
|
||||||
"source_path" : "char-path",
|
"source_path" : "char-path",
|
||||||
@ -329,6 +331,10 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
simple_store_set("fs-mode-combo", VirtualFilesystem.MOUNT_MODES)
|
simple_store_set("fs-mode-combo", VirtualFilesystem.MOUNT_MODES)
|
||||||
self.show_pair_combo("fs-type", self.conn.is_openvz())
|
self.show_pair_combo("fs-type", self.conn.is_openvz())
|
||||||
|
|
||||||
|
# Smartcard widgets
|
||||||
|
combo = self.window.get_widget("smartcard-mode")
|
||||||
|
uihelpers.build_smartcard_mode_combo(self.vm, combo)
|
||||||
|
|
||||||
# Available HW options
|
# Available HW options
|
||||||
is_local = not self.conn.is_remote()
|
is_local = not self.conn.is_remote()
|
||||||
is_storage_capable = self.conn.is_storage_capable()
|
is_storage_capable = self.conn.is_storage_capable()
|
||||||
@ -391,6 +397,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
self.vm.get_hv_type()),
|
self.vm.get_hv_type()),
|
||||||
_("Not supported for this hypervisor/libvirt "
|
_("Not supported for this hypervisor/libvirt "
|
||||||
"combination."))
|
"combination."))
|
||||||
|
add_hw_option("Smartcard", "device_serial", PAGE_SMARTCARD,
|
||||||
|
True, None)
|
||||||
|
|
||||||
def reset_state(self):
|
def reset_state(self):
|
||||||
# Storage init
|
# Storage init
|
||||||
@ -717,6 +725,12 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
|
|
||||||
return combo.get_model()[combo.get_active()][0]
|
return combo.get_model()[combo.get_active()][0]
|
||||||
|
|
||||||
|
# Smartcard getters
|
||||||
|
def get_config_smartcard_mode(self):
|
||||||
|
mode = self.window.get_widget("smartcard-mode")
|
||||||
|
modestr = mode.get_model().get_value(mode.get_active_iter(), 0)
|
||||||
|
return modestr
|
||||||
|
|
||||||
################
|
################
|
||||||
# UI listeners #
|
# UI listeners #
|
||||||
################
|
################
|
||||||
@ -900,6 +914,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
return _("Watchdog Device")
|
return _("Watchdog Device")
|
||||||
if page == PAGE_FILESYSTEM:
|
if page == PAGE_FILESYSTEM:
|
||||||
return _("Filesystem Passthrough")
|
return _("Filesystem Passthrough")
|
||||||
|
if page == PAGE_SMARTCARD:
|
||||||
|
return _("Smartcard")
|
||||||
|
|
||||||
if page == PAGE_CHAR:
|
if page == PAGE_CHAR:
|
||||||
return self.get_char_type().capitalize() + " Device"
|
return self.get_char_type().capitalize() + " Device"
|
||||||
@ -1071,6 +1087,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
return self.validate_page_watchdog()
|
return self.validate_page_watchdog()
|
||||||
elif page_num == PAGE_FILESYSTEM:
|
elif page_num == PAGE_FILESYSTEM:
|
||||||
return self.validate_page_filesystem()
|
return self.validate_page_filesystem()
|
||||||
|
elif page_num == PAGE_SMARTCARD:
|
||||||
|
return self.validate_page_smartcard()
|
||||||
|
|
||||||
def validate_page_storage(self):
|
def validate_page_storage(self):
|
||||||
bus, device = self.get_config_disk_target()
|
bus, device = self.get_config_disk_target()
|
||||||
@ -1328,6 +1346,16 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
return self.err.val_err(_("Filesystem parameter error"),
|
return self.err.val_err(_("Filesystem parameter error"),
|
||||||
str(e))
|
str(e))
|
||||||
|
|
||||||
|
def validate_page_smartcard(self):
|
||||||
|
conn = self.conn.vmm
|
||||||
|
mode = self.get_config_smartcard_mode()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._dev = VirtualSmartCardDevice(conn, mode)
|
||||||
|
except Exception, e:
|
||||||
|
return self.err.val_err(_("Video device parameter error"),
|
||||||
|
str(e))
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Unsorted helpers #
|
# Unsorted helpers #
|
||||||
|
@ -61,12 +61,13 @@ HW_LIST_TYPE_VIDEO = 12
|
|||||||
HW_LIST_TYPE_WATCHDOG = 13
|
HW_LIST_TYPE_WATCHDOG = 13
|
||||||
HW_LIST_TYPE_CONTROLLER = 14
|
HW_LIST_TYPE_CONTROLLER = 14
|
||||||
HW_LIST_TYPE_FILESYSTEM = 15
|
HW_LIST_TYPE_FILESYSTEM = 15
|
||||||
|
HW_LIST_TYPE_SMARTCARD = 16
|
||||||
|
|
||||||
remove_pages = [HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT,
|
remove_pages = [HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT,
|
||||||
HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR,
|
HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR,
|
||||||
HW_LIST_TYPE_HOSTDEV, HW_LIST_TYPE_DISK, HW_LIST_TYPE_VIDEO,
|
HW_LIST_TYPE_HOSTDEV, HW_LIST_TYPE_DISK, HW_LIST_TYPE_VIDEO,
|
||||||
HW_LIST_TYPE_WATCHDOG, HW_LIST_TYPE_CONTROLLER,
|
HW_LIST_TYPE_WATCHDOG, HW_LIST_TYPE_CONTROLLER,
|
||||||
HW_LIST_TYPE_FILESYSTEM]
|
HW_LIST_TYPE_FILESYSTEM, HW_LIST_TYPE_SMARTCARD]
|
||||||
|
|
||||||
# Boot device columns
|
# Boot device columns
|
||||||
BOOT_DEV_TYPE = 0
|
BOOT_DEV_TYPE = 0
|
||||||
@ -360,6 +361,8 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
"on_watchdog_model_combo_changed": self.config_enable_apply,
|
"on_watchdog_model_combo_changed": self.config_enable_apply,
|
||||||
"on_watchdog_action_combo_changed": self.config_enable_apply,
|
"on_watchdog_action_combo_changed": self.config_enable_apply,
|
||||||
|
|
||||||
|
"on_smartcard_mode_combo_changed": self.config_enable_apply,
|
||||||
|
|
||||||
"on_config_apply_clicked": self.config_apply,
|
"on_config_apply_clicked": self.config_apply,
|
||||||
|
|
||||||
"on_details_help_activate": self.show_help,
|
"on_details_help_activate": self.show_help,
|
||||||
@ -776,6 +779,10 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
uihelpers.build_watchdogaction_combo(self.vm, combo,
|
uihelpers.build_watchdogaction_combo(self.vm, combo,
|
||||||
no_default=no_default)
|
no_default=no_default)
|
||||||
|
|
||||||
|
# Smartcard mode
|
||||||
|
sc_mode = self.window.get_widget("smartcard-mode-combo")
|
||||||
|
uihelpers.build_smartcard_mode_combo(self.vm, sc_mode)
|
||||||
|
|
||||||
# Helper function to handle the combo/label pattern used for
|
# Helper function to handle the combo/label pattern used for
|
||||||
# video model, sound model, network model, etc.
|
# video model, sound model, network model, etc.
|
||||||
def set_combo_label(self, prefix, value, model_idx=0, label="",
|
def set_combo_label(self, prefix, value, model_idx=0, label="",
|
||||||
@ -1023,6 +1030,8 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
self.refresh_controller_page()
|
self.refresh_controller_page()
|
||||||
elif pagetype == HW_LIST_TYPE_FILESYSTEM:
|
elif pagetype == HW_LIST_TYPE_FILESYSTEM:
|
||||||
self.refresh_filesystem_page()
|
self.refresh_filesystem_page()
|
||||||
|
elif pagetype == HW_LIST_TYPE_SMARTCARD:
|
||||||
|
self.refresh_smartcard_page()
|
||||||
else:
|
else:
|
||||||
pagetype = -1
|
pagetype = -1
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@ -1630,6 +1639,8 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
ret = self.config_video_apply(key)
|
ret = self.config_video_apply(key)
|
||||||
elif pagetype is HW_LIST_TYPE_WATCHDOG:
|
elif pagetype is HW_LIST_TYPE_WATCHDOG:
|
||||||
ret = self.config_watchdog_apply(key)
|
ret = self.config_watchdog_apply(key)
|
||||||
|
elif pagetype is HW_LIST_TYPE_SMARTCARD:
|
||||||
|
ret = self.config_smartcard_apply(key)
|
||||||
else:
|
else:
|
||||||
ret = False
|
ret = False
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@ -1842,6 +1853,13 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
return self._change_config_helper(self.vm.define_sound_model,
|
return self._change_config_helper(self.vm.define_sound_model,
|
||||||
(dev_id_info, model))
|
(dev_id_info, model))
|
||||||
|
|
||||||
|
# Smartcard options
|
||||||
|
def config_smartcard_apply(self, dev_id_info):
|
||||||
|
model = self.get_combo_label_value("smartcard-mode")
|
||||||
|
if model:
|
||||||
|
return self._change_config_helper(self.vm.define_smartcard_mode,
|
||||||
|
(dev_id_info, model))
|
||||||
|
|
||||||
# Network options
|
# Network options
|
||||||
def config_network_apply(self, dev_id_info):
|
def config_network_apply(self, dev_id_info):
|
||||||
net_list = self.window.get_widget("network-source-combo")
|
net_list = self.window.get_widget("network-source-combo")
|
||||||
@ -2542,6 +2560,13 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
|
|
||||||
self.set_combo_label("sound-model", sound.model)
|
self.set_combo_label("sound-model", sound.model)
|
||||||
|
|
||||||
|
def refresh_smartcard_page(self):
|
||||||
|
sc = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||||
|
if not sc:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set_combo_label("smartcard-mode", sc.mode)
|
||||||
|
|
||||||
def refresh_char_page(self):
|
def refresh_char_page(self):
|
||||||
chardev = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
chardev = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||||
if not chardev:
|
if not chardev:
|
||||||
@ -2912,6 +2937,11 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
_("Filesystem %s") % target,
|
_("Filesystem %s") % target,
|
||||||
gtk.STOCK_DIRECTORY)
|
gtk.STOCK_DIRECTORY)
|
||||||
|
|
||||||
|
# Populate list of smartcard devices
|
||||||
|
for sc in self.vm.get_smartcard_devices():
|
||||||
|
update_hwlist(HW_LIST_TYPE_SMARTCARD, sc,
|
||||||
|
_("Smartcard"), "device_serial")
|
||||||
|
|
||||||
devs = range(len(hw_list_model))
|
devs = range(len(hw_list_model))
|
||||||
devs.reverse()
|
devs.reverse()
|
||||||
for i in devs:
|
for i in devs:
|
||||||
|
@ -47,6 +47,7 @@ def compare_device(origdev, newdev, idx):
|
|||||||
"controller" : ["type", "index"],
|
"controller" : ["type", "index"],
|
||||||
"channel" : ["char_type", "target_name"],
|
"channel" : ["char_type", "target_name"],
|
||||||
"filesystem" : ["target" , "vmmindex"],
|
"filesystem" : ["target" , "vmmindex"],
|
||||||
|
"smartcard" : ["mode" , "vmmindex"],
|
||||||
}
|
}
|
||||||
|
|
||||||
if id(origdev) == id(newdev):
|
if id(origdev) == id(newdev):
|
||||||
@ -633,6 +634,13 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
editdev.action = newval
|
editdev.action = newval
|
||||||
return self._redefine_device(change, devobj)
|
return self._redefine_device(change, devobj)
|
||||||
|
|
||||||
|
# Smartcard define methods
|
||||||
|
|
||||||
|
def define_smartcard_mode(self, devobj, newmodel):
|
||||||
|
def change(editdev):
|
||||||
|
editdev.mode = newmodel
|
||||||
|
return self._redefine_device(change, devobj)
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Hotplug routines #
|
# Hotplug routines #
|
||||||
@ -890,6 +898,8 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
return self._build_device_list("controller")
|
return self._build_device_list("controller")
|
||||||
def get_filesystem_devices(self):
|
def get_filesystem_devices(self):
|
||||||
return self._build_device_list("filesystem")
|
return self._build_device_list("filesystem")
|
||||||
|
def get_smartcard_devices(self):
|
||||||
|
return self._build_device_list("smartcard")
|
||||||
|
|
||||||
def get_disk_devices(self, refresh_if_necc=True, inactive=False):
|
def get_disk_devices(self, refresh_if_necc=True, inactive=False):
|
||||||
devs = self._build_device_list("disk", refresh_if_necc, inactive)
|
devs = self._build_device_list("disk", refresh_if_necc, inactive)
|
||||||
|
@ -214,6 +214,36 @@ def populate_source_mode_combo(vm, combo):
|
|||||||
model.append(["private", "Private"])
|
model.append(["private", "Private"])
|
||||||
model.append(["passthrough", "Passthrough"])
|
model.append(["passthrough", "Passthrough"])
|
||||||
|
|
||||||
|
def build_smartcard_mode_combo(vm, combo):
|
||||||
|
dev_model = gtk.ListStore(str, str)
|
||||||
|
combo.set_model(dev_model)
|
||||||
|
text = gtk.CellRendererText()
|
||||||
|
combo.pack_start(text, True)
|
||||||
|
combo.add_attribute(text, 'text', 1)
|
||||||
|
dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
||||||
|
|
||||||
|
populate_smartcard_mode_combo(vm, combo)
|
||||||
|
|
||||||
|
idx = -1
|
||||||
|
for rowid in range(len(combo.get_model())):
|
||||||
|
idx = 0
|
||||||
|
row = combo.get_model()[rowid]
|
||||||
|
if row[0] == virtinst.VirtualSmartCardDevice.MODE_DEFAULT:
|
||||||
|
idx = rowid
|
||||||
|
break
|
||||||
|
combo.set_active(idx)
|
||||||
|
|
||||||
|
def populate_smartcard_mode_combo(vm, combo):
|
||||||
|
ignore = vm
|
||||||
|
model = combo.get_model()
|
||||||
|
model.clear()
|
||||||
|
|
||||||
|
# [xml value, label]
|
||||||
|
model.append(["passthrough", "Passthrough"])
|
||||||
|
model.append(["host", "Host"])
|
||||||
|
# TODO
|
||||||
|
# model.append(["host-certificates", "Host Certificates"])
|
||||||
|
|
||||||
def build_netmodel_combo(vm, combo):
|
def build_netmodel_combo(vm, combo):
|
||||||
dev_model = gtk.ListStore(str, str)
|
dev_model = gtk.ListStore(str, str)
|
||||||
combo.set_model(dev_model)
|
combo.set_model(dev_model)
|
||||||
|
@ -2204,11 +2204,85 @@ access in the guest.</property>
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">10</property>
|
<property name="position">10</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="page5-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">1</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label8">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Please indicate what smartcard device mode to connect to the virtual machine.</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="left_padding">24</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTable" id="table2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="n_columns">2</property>
|
||||||
|
<property name="column_spacing">12</property>
|
||||||
|
<property name="row_spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="smartcard-mode">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label10">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<property name="label" translatable="yes">_Mode:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">smartcard-mode</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">5</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label14">
|
<widget class="GtkLabel" id="label14">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -5492,6 +5492,106 @@ I/O:</property>
|
|||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox58">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame13">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment159">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="top_padding">3</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTable" id="table36">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">3</property>
|
||||||
|
<property name="n_columns">2</property>
|
||||||
|
<property name="column_spacing">8</property>
|
||||||
|
<property name="row_spacing">4</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label452">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">M_ode:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">smartcard-mode-combo</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox11">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="smartcard-mode-combo">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<signal name="changed" handler="on_smartcard_mode_combo_changed"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="smartcard-mode-label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label">insert smartcard mode</property>
|
||||||
|
<property name="selectable">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
<property name="y_padding">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label451">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes"><b>Smartcard Device</b></property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">label_item</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">9</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label440">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label">snd</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">9</property>
|
||||||
|
<property name="tab_fill">False</property>
|
||||||
|
<property name="type">tab</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
Loading…
Reference in New Issue
Block a user