#!/usr/bin/python2
'''
    This file is part of SSHconf.

    SSHconf 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 3 of the License, or
    (at your option) any later version.

    SSHconf 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 SSHconf.  If not, see <http://www.gnu.org/licenses/>.

    Author: Frank "ancho" Becker 

    Copyright 2010 Frank Becker <ancho@gmx.net>
'''

from PyQt4 import Qt, QtGui, QtCore
from sshconf.gui.qt.view import optionsdialog
from sshconf.gui.qt.view.dialog import Ui_Dialog
from sshconf.gui.qt.view.systray import SSHConfSystemTrayIcon
from sshconf.ssh.sshconfig import LocalForward, RemoteForward
from sshconf.util.command import ProcessManager
from sshconf.util.config import Settings
import logging
import sshconf.ssh.options as options



state2yesno = { QtCore.Qt.Checked   : "yes",
                QtCore.Qt.PartiallyChecked : "ask",
                QtCore.Qt.Unchecked : "no" }
        
yesno2state = { "yes" : QtCore.Qt.Checked,
                "ask" : QtCore.Qt.PartiallyChecked,
                 "no" : QtCore.Qt.Unchecked }

class Widget():
    
    def __init__(self, widget, mediator):
        self._mediator = mediator
        self._widget   = widget
        self._connect()
        
    def changed(self):
        self._mediator.widget_changed(self)
    
    def _connect(self): pass

class DialogManager():
    
    def __init__(self, sshconf, ui):
        self.host     = None
        self._sshconf = sshconf
        self._window  = ui
        self._ui      = ui.ui
        self.log      = logging.getLogger("DialogManager")  
        
    def save_config(self, file = None):
        try:
            self._sshconf.write_config(file)
        except Exception,e:
            QtGui.QMessageBox.critical(self._window,"Error", str(e))
    
          
    def quit(self):
        QtGui.QApplication.quit()
        
            
    def read_config(self):
        
        try:
            self._sshconf.read_config()
        except Exception,e:
            QtGui.QMessageBox.critical(self._window,"Error", str(e))
            self.quit()

        

class SshConfDialogManager( DialogManager ):
    
    def __init__(self, sshconf, ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log    = logging.getLogger("SshConfDialogManager")
        self.read_config()
        
        self.hostsDM = HostsDialogManager(sshconf, ui)
        self.hostsDM.refresh_hostlist()
        
        self.optionsDM = OptionsDialogManager( sshconf, ui )
        
        self.quitaction    = ActionWidget( self._ui.actionQuit,    self )
        self.saveaction    = ActionWidget( self._ui.actionSave,    self )
        self.saveasaction  = ActionWidget( self._ui.actionSave_As, self )
        self.optionsaction = ActionWidget( self._ui.actionOptions, self )
        
    def widget_changed(self, widget):
        
        if( widget == self.quitaction ):
            self.quit()
            
        elif( widget == self.saveaction ):
            self.save_config()
            
        elif( widget == self.saveasaction ):
            self.save_file_dialog()
            
        elif( widget == self.optionsaction ):
            self.optionsDM.start()

    def save_file_dialog(self):
        dir = self._sshconf.get_basename()
        caption = "Save SSH_config File"
        file = QtGui.QFileDialog.getSaveFileName(self._window,caption, dir)
       
        if( file ):
            self.save_config(file)

class SystemTrayDialogManager( DialogManager ):
    
    def __init__(self, handler, sshconf, ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log = logging.getLogger("SystemTrayDialogManager")
        self.handler = handler
        self._create_systray()
        
    def _create_systray(self):
        tray = SSHConfSystemTrayIcon( self._window, self.handler )
        self._tray = SystemTrayWidget( tray, self )
        
    def widget_changed(self, widget):
        # not necessary to do anything here
        pass
        
    def refresh_menu(self, hostnames):
        self._tray.refresh_menu(hostnames)

class HostsDialogManager( DialogManager ):
    
    
    def __init__(self, sshconf, ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log       = logging.getLogger("HostsDialogManager")
        self._add      = ButtonWidget( self._ui.host_addButton, self )
        self._del      = ButtonWidget( self._ui.host_delButton, self )
        self._connect  = ButtonWidget( self._ui.host_connectButton, self )
        self._hostlist = HostListViewWidget( self._ui.host_listView, self )
        self.hostGDM   = HostGeneralDialogManager(sshconf, ui, self)
        self.hostFDM   = HostForwardDialogManager(sshconf, ui)
        self.systrayDM = SystemTrayDialogManager(self, sshconf, ui)
            
        self.procmanager = ProcessManager( self._window, self )
        
        self.hostGDM.enable_tab(False)
        
    
    def widget_changed(self, widget):
        
        if( widget == self._add ):
            self.log.debug("Add Button Changed")
            self.new_host()
            
        elif ( widget == self._del ):
            self.log.debug("Del Button Changed")
            self.del_host()
            
        elif ( widget == self._connect ):
            self.connect_host()
        
        elif ( widget == self._hostlist ):
            self.log.debug("HostListChanged")
            self.selected_host()
            self.log.debug("Connection Event: " + str(self._hostlist.connect) )
            if(self._hostlist.connect):
                self.connect_host()
                
        elif ( widget == self.hostGDM ):
            self.log.debug("Host has changed")
            self.log.debug( str(self.host) )
            self.refresh_hostlist(self.host.get_id())

    def selected_host(self):
        row =  self._hostlist.row
        self.log.debug("Selected row: " + str(row) )
            
        if row != -1:
            self.host = self._sshconf.get_host_manager().get_host_by_index( row )
            self.log.debug( str( self.host ) )
            self.update_hostview()
            self.hostGDM.enable_tab(True)
            
    def edit_host(self, hostname):
        self.host = self._sshconf.get_host_manager().get_host_by_name( hostname )
        self.update_hostview()
        self._hostlist.select( self.host.get_id() )
        
    def new_host(self):
        self.host = self._sshconf.get_host_manager().new_host()
        self.update_hostview()
        self.refresh_hostlist(1)
        
    def del_host(self):
        self._sshconf.get_host_manager().del_host( self.host )
        self.save_config()
        self.refresh_hostlist()
        
    def connect_host(self, hostname=None):
        settings = Settings()
        
        terminal = settings.get_prog()
        if( hostname == None ):
            hostname = self.host.get_option(options.oHost)
            
        cmd = "ssh %s" % hostname
        title = "SSH: %s" % hostname
        flags  = settings.get_titleflag() + ' "%s" -e %s' % ( title, cmd )

        sshcmd = 'ssh -o "BatchMode=yes" -o "ClearAllForwardings=yes" %s exit' % hostname
        self.procmanager.new(sshcmd)
        self.log.info("Test ssh connection with: " + hostname)
                    
        terminalcmnd = terminal + " " + flags
        self.procmanager.new(terminalcmnd)
        self.log.info("Open Terminal with ssh connection to: " + hostname)
    
    def update_hostview(self):
        self._ui.hostGroupBox.setTitle( self.host.get_option(options.oHost) )
        self.hostGDM.host = self.host
        self.hostGDM.update_hostview()
        self.hostFDM.host = self.host
        self.hostFDM.update_hostview()
        
    def refresh_hostlist(self,index=None):
        hostnamelist = self._sshconf.get_host_manager().get_host_names()
        self._hostlist.refresh(hostnamelist)
        self._hostlist.select(index)
        self.systrayDM.refresh_menu(hostnamelist)
    
    #callback method for processmanager
    def do_process_finished(self,proc, retval):
        self.log.debug("Return value: " + str(retval) )
        self.log.debug("Stdout: " + str(proc.readAllStandardOutput() ) )
        self.log.debug("Stderr: " + str(proc.readAllStandardError() ) )
        if( retval == 255 ):
            QtGui.QMessageBox.critical(self.main,"Connection Error", str( proc.readAllStandardError() ) )
        
        self.log.debug(str(self.procmanager))
        self.procmanager.del_proc(proc)
    
        

class HostGeneralDialogManager( DialogManager, Widget ):
    
    def __init__(self, sshconf, ui, mediator):
        DialogManager.__init__(self, sshconf, ui)
        Widget.__init__(self, self, mediator)
        self.log        = logging.getLogger("HostGeneralDialogManager")
        self._host      = LineEditWidget( self._ui.host_lineEdit, self ) 
        self._hostname  = LineEditWidget( self._ui.hostname_lineEdit, self )
        self._port      = LineEditWidget( self._ui.port_lineEdit, self )
        self._user      = LineEditWidget( self._ui.user_lineEdit, self )
        
        self._fwdx11    = CheckBoxWidget( self._ui.ForwardX11_checkBox, self )
        self._fwdx11trusted = CheckBoxWidget( self._ui.ForwardX11Trusted_checkBox, self )
        
        self._compress  = CheckBoxWidget( self._ui.Compression_checkBox, self )
        self._clearAF   = CheckBoxWidget( self._ui.ClearAllForwardings_checkBox, self )
        
        
        self._checkhostIP   = CheckBoxWidget( self._ui.CheckHostIP_checkBox, self )
        self._exitonfwd     = CheckBoxWidget( self._ui.ExitOnForwardFailure_checkBox, self )
        self._fwdagent      = CheckBoxWidget( self._ui.ForwardAgent_checkBox, self )
        self._CRA           = CheckBoxWidget( self._ui.ChallengeResponseAuth_checkBox, self )
        self._gwports       = CheckBoxWidget( self._ui.GatewayPorts_checkBox, self )
        self._gssapiauth    = CheckBoxWidget( self._ui.GSSAPIAuth_checkBox, self )
        self._gssapikey     = CheckBoxWidget( self._ui.GSSAPIKeyExchange_checkBox, self )
        self._gssapidelegate= CheckBoxWidget( self._ui.GSSAPIDelegateCredentials_checkBox, self )
        self._gssapitrust   = CheckBoxWidget( self._ui.GSSAPITrustDns_checkBox, self )
        self._hostbasedauth = CheckBoxWidget( self._ui.HostbasedAuth_checkBox, self )
        self._identonly     = CheckBoxWidget( self._ui.IdentitiesOnly_checkBox, self )
        self._kbdinteractive= CheckBoxWidget( self._ui.KbdInteractiveAuth_checkBox, self )
        self._pwdauth       = CheckBoxWidget( self._ui.PasswordAuth_checkBox, self )
        self._permitlocal   = CheckBoxWidget( self._ui.PermitLocalCommand_checkBox, self )
        self._pubkeyauth    = CheckBoxWidget( self._ui.PubkeyAuth_checkBox, self )
        self._rhostrsa      = CheckBoxWidget( self._ui.RhostsRSAAuth_checkBox, self )
        self._rsaauth       = CheckBoxWidget( self._ui.RSAAuth_checkBox, self )
        self._strictkeychk  = CheckBoxWidget( self._ui.StrictHostKeyChecking_checkBox, self )
        self._tcpkeepalive  = CheckBoxWidget( self._ui.TCPKeepAlive_checkBox, self )
        self._tunnel        = CheckBoxWidget( self._ui.Tunnel_checkBox, self )
        self._useblacklist  = CheckBoxWidget( self._ui.UseBlacklistedKeys_checkBox, self )
        self._useprivport   = CheckBoxWidget( self._ui.UsePrivilegedPort_checkBox, self )
        self._verifyhostkey = CheckBoxWidget( self._ui.VerifyHostKeyDNS_checkBox, self )
        self._visualhostkey = CheckBoxWidget( self._ui.VisualHostKey_checkBox, self )

        
        self._compressLevelSlider  = SliderWidget( self._ui.compressLevelSlider, self )
        self._compressLevelSpinBox = SpinBoxWidget( self._ui.compressLevel_spinBox, self ) 
        
    def update_hostview(self):
        self._enable_events = False
        self._host      .set_text( self.host.get_option(options.oHost) )
        self._hostname  .set_text( self.host.get_option(options.oHostName) )
        self._port      .set_text( self.host.get_option(options.oPort) )
        self._user      .set_text( self.host.get_option(options.oUser) )
        self._fwdx11    .set_state( self.host.get_option(options.oForwardX11) )
        self._fwdx11trusted.set_state( self.host.get_option(options.oForwardX11Trusted) )
        self._compress  .set_state( self.host.get_option(options.oCompression) )
        self._clearAF   .set_state( self.host.get_option(options.oClearAllForwardings) )
        self._checkhostIP.set_state( self.host.get_option(options.oCheckHostIP) )
        self._CRA.set_state( self.host.get_option(options.oChallengeResponseAuthentication) )
        self._exitonfwd.set_state( self.host.get_option(options.oExitOnForwardFailure) )
        self._fwdagent.set_state( self.host.get_option(options.oForwardAgent) )
        self._gwports.set_state( self.host.get_option(options.oGatewayPorts) )
        self._gssapiauth.set_state( self.host.get_option(options.oGSSAPIAuthentication) )
        self._gssapidelegate.set_state( self.host.get_option(options.oGSSAPIDelegateCredentials) )
        self._gssapikey.set_state( self.host.get_option(options.oGSSAPIKeyExchange) )
        self._gssapitrust.set_state( self.host.get_option(options.oGSSAPITrustDns) )
        self._hostbasedauth.set_state( self.host.get_option(options.oHostbasedAuthentication) )        
        self._identonly.set_state( self.host.get_option(options.oIdentitiesOnly) )
        self._kbdinteractive.set_state( self.host.get_option(options.oKbdInteractiveAuthentication) )
        self._pwdauth.set_state( self.host.get_option(options.oPasswordAuthentication) )
        self._permitlocal.set_state( self.host.get_option(options.oPermitLocalCommand) )
        self._pubkeyauth.set_state( self.host.get_option(options.oPubkeyAuthentication) )
        self._rhostrsa.set_state( self.host.get_option(options.oRhostsRSAAuthentication) )
        self._rsaauth.set_state( self.host.get_option(options.oRSAAuthentication) )
        self._strictkeychk.set_state( self.host.get_option(options.oStrictHostKeyChecking) )
        self._tcpkeepalive.set_state( self.host.get_option(options.oTCPKeepAlive) )
        self._tunnel.set_state( self.host.get_option(options.oTunnel) )
        self._useblacklist.set_state( self.host.get_option(options.oUseBlacklistedKeys) )
        self._useprivport.set_state( self.host.get_option(options.oUsePrivilegedPort) )
        self._verifyhostkey.set_state( self.host.get_option(options.oVerifyHostKeyDNS) )
        self._visualhostkey.set_state( self.host.get_option(options.oVisualHostKey) )
        self._compressLevelSlider.set_value( self.host.get_option(options.oCompressionLevel) )
        self._enable_events = True

    def update_host(self):
        old_host = self.host
        
        #delete old host from host list
        self._sshconf.get_host_manager().del_host( old_host )
        self.host.set_option(options.oHost, self._host.get_text() )
        self.host.set_option(options.oHostName, self._hostname.get_text() )
        self.host.set_option(options.oPort, self._port.get_text() )
        self.host.set_option(options.oUser, self._user.get_text() )
        self.host.set_option(options.oForwardX11, self._fwdx11.get_state() )
        self.host.set_option(options.oForwardX11Trusted, self._fwdx11trusted.get_state() )
        self.host.set_option(options.oCompression, self._compress.get_state() )
        self.host.set_option(options.oCompressionLevel, self._compressLevelSlider.get_value() )
        self.host.set_option(options.oClearAllForwardings, self._clearAF.get_state() )
        self.host.set_option(options.oChallengeResponseAuthentication, self._CRA.get_state() )
        self.host.set_option(options.oCheckHostIP, self._checkhostIP.get_state() )
        self.host.set_option(options.oExitOnForwardFailure, self._exitonfwd.get_state() )
        self.host.set_option(options.oForwardAgent, self._fwdagent.get_state() )
        self.host.set_option(options.oGatewayPorts, self._gwports.get_state() )
        self.host.set_option(options.oGSSAPIAuthentication, self._gssapiauth.get_state() )
        self.host.set_option(options.oGSSAPIDelegateCredentials, self._gssapidelegate.get_state() )
        self.host.set_option(options.oGSSAPIKeyExchange, self._gssapikey.get_state() )
        self.host.set_option(options.oGSSAPITrustDns, self._gssapitrust.get_state() )
        self.host.set_option(options.oHostbasedAuthentication, self._hostbasedauth.get_state() )
        self.host.set_option(options.oIdentitiesOnly, self._identonly.get_state() )
        self.host.set_option(options.oKbdInteractiveAuthentication, self._kbdinteractive.get_state() )
        self.host.set_option(options.oPasswordAuthentication, self._pwdauth.get_state() )
        self.host.set_option(options.oPermitLocalCommand, self._permitlocal.get_state() )
        self.host.set_option(options.oPubkeyAuthentication, self._pubkeyauth.get_state() )
        self.host.set_option(options.oRhostsRSAAuthentication, self._rhostrsa.get_state() )
        self.host.set_option(options.oRSAAuthentication, self._rsaauth.get_state() )
        self.host.set_option(options.oStrictHostKeyChecking, self._strictkeychk.get_state() )
        self.host.set_option(options.oTCPKeepAlive, self._tcpkeepalive.get_state() )
        self.host.set_option(options.oTunnel, self._tunnel.get_state() )
        self.host.set_option(options.oUseBlacklistedKeys, self._useblacklist.get_state() )
        self.host.set_option(options.oUsePrivilegedPort, self._useprivport.get_state() )
        self.host.set_option(options.oVerifyHostKeyDNS, self._verifyhostkey.get_state() )
        self.host.set_option(options.oVisualHostKey, self._visualhostkey.get_state() )
        
        #add changed host to host list
        self._sshconf.get_host_manager().add_host( self.host )
        self.changed()
        
        
    def widget_changed(self, widget):
        
        if self._enable_events:
            if (  widget == self._host      or
                  widget == self._hostname  or
                  widget == self._port      or
                  widget == self._user      or
                  widget == self._fwdx11    or
                  widget == self._fwdx11trusted or
                  widget == self._compress  or
                  widget == self._clearAF   or
                  widget == self._CRA   or
                  widget == self._checkhostIP   or
                  widget == self._exitonfwd  or
                  widget == self._fwdagent or
                  widget == self._gwports  or
                  widget == self._gssapiauth   or
                  widget == self._gssapidelegate   or
                  widget == self._gssapikey   or
                  widget == self._gssapitrust   or
                  widget == self._hostbasedauth   or
                  widget == self._identonly   or
                  widget == self._kbdinteractive   or
                  widget == self._pwdauth   or
                  widget == self._permitlocal   or
                  widget == self._pubkeyauth   or
                  widget == self._rhostrsa   or
                  widget == self._rsaauth   or
                  widget == self._strictkeychk   or
                  widget == self._tcpkeepalive   or
                  widget == self._tunnel   or
                  widget == self._useblacklist   or
                  widget == self._useprivport   or
                  widget == self._verifyhostkey   or
                  widget == self._visualhostkey      ):
                
                self.save()
                
            elif( widget == self._compressLevelSlider ):
                self._compressLevelSpinBox.set_value( self._compressLevelSlider.get_value() )
                self.save()
                
            elif( widget == self._compressLevelSpinBox ):
                self._compressLevelSlider.set_value( self._compressLevelSpinBox.get_value() )
                self.save()
    
    def host_exist(self):
        ret = False
        e_host = self._sshconf.get_host_manager().get_host_by_name( self._host.get_text() )
        
        if( e_host != None ):
            if(e_host.get_id() != self.host.get_id()):
                ret = True
                QtGui.QMessageBox.critical(self._window,"Error", "A host with the Name: " + e_host.get_option(options.oHost) + " already exist")
            
        return ret
    
    def save(self):
        
        if not self.host_exist():
            self.update_host()
            self.save_config()
        else:
            self._host.set_text( self.host.get_option(options.oHost) )
            
    def enable_tab(self, boolean):
        self._ui.hostGroupBox.setEnabled(boolean)

class HostForwardDialogManager( DialogManager ):
    
    def __init__(self,sshconf,ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log = logging.getLogger("HostForwardDialogManager")
        self._lfwd_edit = ButtonWidget( self._ui.lfwd_editButton, self )
        self._lfwd_add  = ButtonWidget( self._ui.lfwd_addButton, self )
        self._lfwd_del  = ButtonWidget( self._ui.lfwd_delButton, self )
        self._lfwd_list = ForwardListViewWidget( self._ui.localforward_listView, self )

        self._rfwd_edit = ButtonWidget( self._ui.rfwd_editButton, self )
        self._rfwd_add  = ButtonWidget( self._ui.rfwd_addButton, self )
        self._rfwd_del  = ButtonWidget( self._ui.rfwd_delButton, self )       
        self._rfwd_list = ForwardListViewWidget( self._ui.remoteforward_listView, self )
        
        self.editforwardDM = EditForwardDialogManager(sshconf, ui)
        
    def widget_changed(self, widget):
        
        if ( widget == self._lfwd_edit ):
            self.log.debug("Edit LocalForward: " + str(self._lfwd_list.row) )
            self.edit_localforward()
            self.log.debug("Refresh Forward List")
            self.refresh_localforward_list()
        
        elif ( widget == self._lfwd_add ):
            self.log.debug("Add LocalForward")
            self.add_localforward()
            new = True
            self.edit_localforward(new)
            self.log.debug("Refresh Forward List")
            self.refresh_localforward_list()
            
            
        elif ( widget == self._lfwd_del ):
            self.log.debug("Delete LocalForward")
            self.del_localforward()   

        elif ( widget == self._rfwd_edit ):
            self.log.debug("Edit RemoteForward: " + str(self._rfwd_list.row) )
            self.edit_remoteforward()
            self.log.debug("Refresh Remote Forward List")
            self.refresh_remoteforward_list()

        
        elif ( widget == self._rfwd_add ):
            self.log.debug("Add RemoteForward")
            self.add_remoteforward()
            new = True
            self.edit_remoteforward(new)
            self.log.debug("Refresh Remote Forward List")
            self.refresh_remoteforward_list()
            
        elif ( widget == self._rfwd_del ):
            self.log.debug("Delete RemoteForward")
            self.del_remoteforward()   
   
    
    def refresh_localforward_list(self):
        list = self.host.get_local_forward_manager().get_forward_list()
        self._lfwd_list.refresh(list)

    def refresh_remoteforward_list(self):
        list = self.host.get_remote_forward_manager().get_forward_list()
        self._rfwd_list.refresh(list)
    
    def update_hostview(self):
        self.refresh_localforward_list()
        self.refresh_remoteforward_list() 

    def _add_forward(self, fwd, fwd_manager, callback):
        fwd_manager.add_forward(fwd)
        callback()
        
    def _del_forward(self,index, fwd_manager, callback):
        if( index > -1 ):
            fwd = fwd_manager.get_forward_by_index(index)
            fwd_manager.del_forward(fwd)
            callback()
            self.save_config()
    
    def _edit_forward(self,index,new,fwd_manager, callback):
        if( index > -1 ):
            fwd = fwd_manager.get_forward_by_index(index)
            accepted = self.editforwardDM.start(fwd, new)
            if( not accepted ):
                self._del_forward(index, fwd_manager, callback)
            else:
                self.save_config()
        
    def edit_localforward(self, new = False):
        index = self._lfwd_list.row

        fwd_manager = self.host.get_local_forward_manager()
        callback = self.refresh_localforward_list
        
        self._edit_forward(index, new, fwd_manager, callback)
    
    def edit_remoteforward(self, new = False):
        index = self._rfwd_list.row

        fwd_manager = self.host.get_remote_forward_manager()
        callback = self.refresh_remoteforward_list
        
        self._edit_forward(index, new, fwd_manager, callback)
    
    def add_localforward(self):
        fwd = LocalForward( 0, "localhost", 0, "localhost" )
        fwd_manager = self.host.get_local_forward_manager()
        callback = self.refresh_localforward_list
        
        self._add_forward(fwd, fwd_manager, callback)
        self._lfwd_list.select()

    def del_localforward(self):
        index = self._lfwd_list.row
        fwd_manager = self.host.get_local_forward_manager()
        callback = self.refresh_localforward_list
        
        self._del_forward(index, fwd_manager, callback)
        
    def add_remoteforward(self):
        fwd = RemoteForward( 0, "localhost", 0, "localhost" )
        fwd_manager = self.host.get_remote_forward_manager()
        callback = self.refresh_remoteforward_list
        
        self._add_forward(fwd, fwd_manager, callback)
        self._rfwd_list.select()

    def del_remoteforward(self):
        index = self._rfwd_list.row
        fwd_manager = self.host.get_remote_forward_manager()
        callback = self.refresh_remoteforward_list
        
        self._del_forward(index, fwd_manager, callback)

class EditForwardDialogManager( DialogManager ):
    
    def __init__(self, sshconf, ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log = logging.getLogger("EditForwardDialogManager")
        
    def widget_changed(self, widget):
        
        if ( widget == self.dialog ):
            self.log.debug("Dialog finished: " + str( self.dialog.get_result() ) )
            if ( self.dialog.get_result() == 1 ):
                self.update_forward()
            
            
    def _setup_dialog(self):
        newdialog = QtGui.QDialog()
        self.dialog = DialogWidget( newdialog , self )
        self.editui = Ui_Dialog()
        self.editui.setupUi(newdialog)
        
        self.editui.lhost_lineEdit.insert( self.fwd.get_bind_address() )
        self.editui.lport_lineEdit.insert( str( self.fwd.get_port() ) )
        self.editui.rhost_lineEdit.insert( self.fwd.get_host() )
        self.editui.rport_lineEdit.insert( str( self.fwd.get_host_port() ) )
        
    def start(self, fwd, new = False):
        self.new = new
        self.fwd = fwd
        self._setup_dialog()
        accepted = self.dialog.execute()
        
        if not accepted and new :
            return False
        else:
            return True
        
    def update_forward(self):
        
        lhost = str( self.editui.lhost_lineEdit.text() )
        lport = str( self.editui.lport_lineEdit.text() )
        rhost = str( self.editui.rhost_lineEdit.text() )
        rport = str( self.editui.rport_lineEdit.text() )
        
        self.fwd.set_bind_address( lhost )
        self.fwd.set_port( lport )
        self.fwd.set_host( rhost )
        self.fwd.set_host_port( rport )

class OptionsDialogManager( DialogManager ):
    
    def __init__(self, sshconf, ui):
        DialogManager.__init__(self, sshconf, ui)
        self.log = logging.getLogger("OptionsDialogManager")

    def _setup_dialog(self):
        newdialog = QtGui.QDialog()
        self.dialog = DialogWidget( newdialog , self )
        self.optionsui = optionsdialog.Ui_Dialog()
        self.optionsui.setupUi(newdialog)
        self._path    = LineEditWidget( self.optionsui.path_lineEdit     , self )
        self._logfile = LineEditWidget( self.optionsui.logfile_lineEdit  , self )
        self._prog    = LineEditWidget( self.optionsui.program_lineEdit  , self )
        self._flag    = LineEditWidget( self.optionsui.titleflag_lineEdit, self )
    
    def start(self):
        self._setup_dialog()
        self.update_options_view()
        self.dialog.execute()   
    
    def widget_changed(self, widget):
        
        if( widget == self.dialog ):
            self.log.debug("Dialog finished: " + str( self.dialog.get_result() ) )
            if ( self.dialog.get_result() == 1 ):
                self.update_options()         
                
    def update_options(self):
        settings = Settings()
        settings.set_path( self._path.get_text() )
        settings.set_logfile( self._logfile.get_text() )
        settings.set_prog( self._prog.get_text() )
        settings.set_title_flag( self._flag.get_text() )
        settings.save_config()
        del( settings ) 
    
    def update_options_view(self):
        settings = Settings()
        self._path.set_text( settings.get_path() )
        self._logfile.set_text( settings.get_logfile() )
        self._prog.set_text( settings.get_prog() )
        self._flag.set_text( settings.get_titleflag() )
        del(settings)
        
             

    
class ButtonWidget( Widget ):
    
            
    def _connect(self):
        self._widget.clicked.connect( self.changed )
        
    def enable(self, boolean):
        self._widget.setEnabled(boolean)
    
    def set_textcolor(self, color):
        palette = self._widget.palette()
        palette.setColor(Qt.QPalette.ButtonText, color )
        self._widget.setPalette( palette )
    
    def set_red_textcolor(self):
        color = Qt.QColor( 255, 0, 0 )
        self.set_textcolor(color)
        
    def set_black_textcolor(self):
        color = Qt.QColor( 0, 0, 0 )
        self.set_textcolor(color)
    

class SliderWidget( Widget ):
    
    def _connect(self):
        self._widget.valueChanged.connect( self.changed )
        
    def set_value(self, value):
        self._widget.setValue( int(value) )
    
    def get_value(self):
        return self._widget.value()
        
class SpinBoxWidget( Widget ):
    
    def _connect(self):
        self._widget.valueChanged.connect( self.changed )
        
    def set_value(self, value):
        self._widget.setValue( int(value) )
    
    def get_value(self):
        return self._widget.value()


class CheckBoxWidget( Widget ):
    
    def _connect(self):
        self._widget.stateChanged.connect( self.changed )
    
    def set_state(self, state):
        self._widget.setCheckState( yesno2state[ state ] )
        
    def get_state(self):
        state = self._widget.checkState()
        return state2yesno[ state ]
    
class LineEditWidget( Widget ):
    
    def _connect(self):
        self._widget.editingFinished.connect( self.changed )
    
    def get_text(self):
        return self._widget.text()
    
    def set_text(self, text):
        self._widget.clear()
        self._widget.insert(text)
       
class ListViewWidget( Widget ):
    
    def __init__(self, widget, mediator):
        Widget.__init__(self, widget, mediator)
        self.row = -1 
        self.log = logging.getLogger("ListViewWidget")

        
    def select(self, index = None):
        
        if( index != None ):
            size = index - 1
        else:
            size = self._widget.count() -1
                
        if( size > -1 ):
            self.log.debug("%s: Selected Item: %s" %(self._widget,size))
            self._widget.setCurrentRow( size )
            self._selected()   
        
    def refresh(self, list):
        
        self._widget.clear()
        for item in list:
            self._widget.addItem(str(item))


class ForwardListViewWidget( ListViewWidget ):
    
    def _connect(self):
        self.edit = False
        self._widget.itemPressed.connect( self._selected )
        self._widget.itemDoubleClicked.connect(self._edit_forward)
        
    def _selected(self):
        self.row = self._widget.currentRow()
        self.edit = False
        self.changed()
        
    def _edit_forward(self):
        self.edit = True
        self.changed()
    
          
class HostListViewWidget( ListViewWidget ):
        
    def _connect(self):
        self.connect = False
        self._widget.itemPressed.connect( self._selected )
        self._widget.itemDoubleClicked.connect(self._connect_host)
        self.log = logging.getLogger("HostListViewWidget")
        
    
    def _connect_host(self):
        self.connect = True
        self.changed()
    
    def _selected(self):
        self.row = self._widget.currentRow()
        self.connect = False
        self.changed()
    
class DialogWidget( Widget ):

    def _connect(self):
        self._widget.finished.connect( self.changed )
    
    def get_result(self):
        return self._widget.result()
        
    def execute(self):
        ret = self._widget.exec_()
        
        return ret
    
class SystemTrayWidget( Widget ):
    
    def _connect(self):
        pass

    def _activated(self, types):
        if types == QtGui.QSystemTrayIcon.Trigger:
            self.changed()
        else:
            pass 
        
    def refresh_menu(self, hostnames):
        self._widget.update_menu( hostnames ) 
    
    
class ActionWidget( Widget ):
    
    def _connect(self):
        self._widget.triggered.connect( self.changed )
