2014-01-28 13:51:59 -05:00
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
from gi . repository import Gtk
2014-09-12 16:10:45 -04:00
from . import uiutil
from . baseclass import vmmGObjectUI
2014-01-28 13:51:59 -05:00
class vmmMediaCombo ( vmmGObjectUI ) :
OPTICAL_FIELDS = 4
( OPTICAL_DEV_PATH ,
OPTICAL_LABEL ,
OPTICAL_HAS_MEDIA ,
OPTICAL_DEV_KEY ) = range ( OPTICAL_FIELDS )
def __init__ ( self , conn , builder , topwin , media_type ) :
vmmGObjectUI . __init__ ( self , None , None , builder = builder , topwin = topwin )
self . conn = conn
self . media_type = media_type
self . top_box = None
self . combo = None
self . _warn_icon = None
self . _populated = False
self . _init_ui ( )
def _cleanup ( self ) :
try :
self . conn . disconnect_by_func ( self . _mediadev_added )
self . conn . disconnect_by_func ( self . _mediadev_removed )
except :
pass
self . conn = None
self . top_box . destroy ( )
self . top_box = None
##########################
# Initialization methods #
##########################
def _init_ui ( self ) :
self . top_box = Gtk . Box ( )
self . top_box . set_spacing ( 6 )
self . top_box . set_orientation ( Gtk . Orientation . HORIZONTAL )
self . _warn_icon = Gtk . Image ( )
self . _warn_icon . set_from_stock (
Gtk . STOCK_DIALOG_WARNING , Gtk . IconSize . MENU )
self . combo = Gtk . ComboBox ( )
self . top_box . add ( self . combo )
self . top_box . add ( self . _warn_icon )
self . top_box . show_all ( )
# [Device path, pretty label, has_media?, device key, media key,
# vmmMediaDevice, is valid device]
fields = [ ]
fields . insert ( self . OPTICAL_DEV_PATH , str )
fields . insert ( self . OPTICAL_LABEL , str )
fields . insert ( self . OPTICAL_HAS_MEDIA , bool )
fields . insert ( self . OPTICAL_DEV_KEY , str )
self . combo . set_model ( Gtk . ListStore ( * fields ) )
text = Gtk . CellRendererText ( )
self . combo . pack_start ( text , True )
self . combo . add_attribute ( text , ' text ' , self . OPTICAL_LABEL )
error = self . conn . mediadev_error
self . _warn_icon . set_visible ( bool ( error ) )
self . _warn_icon . set_tooltip_text ( error )
def _set_mediadev_default ( self ) :
model = self . combo . get_model ( )
if len ( model ) != 0 :
return
row = [ None ] * self . OPTICAL_FIELDS
row [ self . OPTICAL_DEV_PATH ] = None
row [ self . OPTICAL_LABEL ] = _ ( " No device present " )
row [ self . OPTICAL_HAS_MEDIA ] = False
row [ self . OPTICAL_DEV_KEY ] = None
model . append ( row )
def _set_mediadev_row_from_object ( self , row , obj ) :
row [ self . OPTICAL_DEV_PATH ] = obj . get_path ( )
row [ self . OPTICAL_LABEL ] = obj . pretty_label ( )
row [ self . OPTICAL_HAS_MEDIA ] = obj . has_media ( )
row [ self . OPTICAL_DEV_KEY ] = obj . get_key ( )
def _mediadev_set_default_selection ( self ) :
# Set the first active cdrom device as selected, otherwise none
widget = self . combo
model = widget . get_model ( )
idx = 0
active = widget . get_active ( )
if active != - 1 :
# already a selection, don't change it
return
for row in model :
if row [ self . OPTICAL_HAS_MEDIA ] is True :
widget . set_active ( idx )
return
idx + = 1
widget . set_active ( 0 )
def _mediadev_media_changed ( self , newobj ) :
widget = self . combo
model = widget . get_model ( )
active = widget . get_active ( )
idx = 0
# Search for the row with matching device node and
# fill in info about inserted media. If model has no current
# selection, select the new media.
for row in model :
if row [ self . OPTICAL_DEV_PATH ] == newobj . get_path ( ) :
self . _set_mediadev_row_from_object ( row , newobj )
has_media = row [ self . OPTICAL_HAS_MEDIA ]
if has_media and active == - 1 :
widget . set_active ( idx )
elif not has_media and active == idx :
widget . set_active ( - 1 )
idx = idx + 1
self . _mediadev_set_default_selection ( )
def _mediadev_added ( self , ignore , newobj ) :
widget = self . combo
model = widget . get_model ( )
if newobj . get_media_type ( ) != self . media_type :
return
if model is None :
return
if len ( model ) == 1 and model [ 0 ] [ self . OPTICAL_DEV_PATH ] is None :
# Only entry is the 'No device' entry
model . clear ( )
newobj . connect ( " media-added " , self . _mediadev_media_changed )
newobj . connect ( " media-removed " , self . _mediadev_media_changed )
# Brand new device
row = [ None ] * self . OPTICAL_FIELDS
self . _set_mediadev_row_from_object ( row , newobj )
model . append ( row )
self . _mediadev_set_default_selection ( )
def _mediadev_removed ( self , ignore , key ) :
widget = self . combo
model = widget . get_model ( )
active = widget . get_active ( )
idx = 0
for row in model :
if row [ self . OPTICAL_DEV_KEY ] == key :
# Whole device removed
del ( model [ idx ] )
if idx > active and active != - 1 :
widget . set_active ( active - 1 )
elif idx == active :
widget . set_active ( - 1 )
idx + = 1
self . _set_mediadev_default ( )
self . _mediadev_set_default_selection ( )
def _populate_media ( self ) :
if self . _populated :
return
widget = self . combo
model = widget . get_model ( )
model . clear ( )
self . _set_mediadev_default ( )
self . conn . connect ( " mediadev-added " , self . _mediadev_added )
self . conn . connect ( " mediadev-removed " , self . _mediadev_removed )
widget . set_active ( - 1 )
self . _mediadev_set_default_selection ( )
self . _populated = True
##############
# Public API #
##############
def reset_state ( self ) :
self . _populate_media ( )
def get_path ( self ) :
return uiutil . get_list_selection ( self . combo , self . OPTICAL_DEV_PATH )
def has_media ( self ) :
return uiutil . get_list_selection ( self . combo , self . OPTICAL_HAS_MEDIA )