# -*- coding: latin-1 -*-
"""
Clases para el manejo de los controles de una forma más sencilla.
"""

from PySide import QtCore, QtGui

#==========================================================================================================================================
class ED(QtGui.QLineEdit):
    """
    Control de entrada de texto en una línea.
    """

    #--------------------------------------------------------------------------
    def __init__(self, parent, texto = None ):
        """
        @param parent: ventana propietaria.
        @param texto: texto inicial.
        """
        if texto :
            QtGui.QLineEdit.__init__(self, texto, None)
        else :
            QtGui.QLineEdit.__init__(self, None)
        self.parent = parent

        self.siMayusculas = False

        self.menu = None

    #--------------------------------------------------------------------------
    def soloLectura( self, sino ) :
        self.setReadOnly( sino )
        return self

    #--------------------------------------------------------------------------
    def password( self ) :
        self.setEchoMode(QtGui.QLineEdit.Password)
        return self

    #--------------------------------------------------------------------------
    def deshabilitado( self, sino ) :
        self.setDisabled( sino )
        return self

    #--------------------------------------------------------------------------
    def capturaIntro( self, rutina ) :
        """
        Si se pulsa un intro en el campo, se lanza la rutina
        """
        self.parent.connect( self, QtCore.SIGNAL( "returnPressed()" ), rutina )
        return self

    #--------------------------------------------------------------------------
    def ponTexto(self, texto) :
        """
        Pone el texto en el campo.
        """
        self.setText( texto )

    #--------------------------------------------------------------------------
    def texto(self) :
        """
        Devuelve el texto del campo.
        """
        txt = str(self.text( ))
        return txt

    #--------------------------------------------------------------------------
    def alinCentrado( self ) :
        """
        Alinea al centro.
        """
        self.setAlignment( QtCore.Qt.AlignHCenter )
        return self

    #--------------------------------------------------------------------------
    def alinDerecha( self ) :
        """
        Alinea a la derecha.
        """
        self.setAlignment( QtCore.Qt.AlignRight )
        return self

    #--------------------------------------------------------------------------
    def anchoMinimo( self, tam ) :
        """
        Ancho mínimo en pixeles
        """
        self.setMinimumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def anchoMaximo( self, tam ) :
        """
        Ancho máximo en pixeles
        """
        self.setMaximumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def caracteres( self, num ) :
        """
        Número máximo de caracteres.
        @param num: número de caracteres máximo que puede contener.
        """
        self.setMaxLength( num )
        self.numCaracteres = num
        return self

    #--------------------------------------------------------------------------
    def anchoFijo( self, tam ) :
        """
        Ancho fijo del campo.
        @param tam: tamaño en pixeles.
        """
        self.setFixedWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def controlrx( self, regexpr ) :
        """
        Valida los caracteres introducidos en base a una expresión regular
        """
        rx = QtCore.QRegExp( regexpr )
        validator = QtGui.QRegExpValidator( rx, self )
        self.setValidator( validator )
        return self

    #--------------------------------------------------------------------------
    def ponFuente( self, f ) :
        """
        Pone el tipo de letra f
        """
        self.setFont( f )
        return self

    #--------------------------------------------------------------------------
    def tipoFloat( self, valor=0.0, desde = 0.0, hasta = 36000.0, decimales = 1 ) :
        """
        Valida los caracteres suponiendo que es un tipo decimal con unas condiciones
        @param valor: valor inicial
        @param desde: valor mínimo
        @param hasta: valor máximo
        @param decimales: num. decimales
        """
        self.decimales = decimales
        if desde == None :
            self.setValidator(QtGui.QDoubleValidator(self))
        else :
            self.setValidator(QtGui.QDoubleValidator(desde, hasta, decimales, self))
        self.setAlignment(QtCore.Qt.AlignRight)
        self.ponFloat( valor )
        return self

    def ponFloat( self, valor ) :
        """
        Pone el número decimal en el campo
        """
        fm = "%0."+str(self.decimales)+"f"
        self.ponTexto( fm%valor )
        return self

    def textoFloat(self) :
        """
        Recupera el número decimal del campo.
        """
        txt = str(self.text( ))
        return round(float(txt),self.decimales) if txt else 0.0

    #--------------------------------------------------------------------------
    def tipoInt( self, valor = 0 ) :
        """
        Valida los caracteres suponiendo que es un tipo entero con unas condiciones
        @param valor: valor inicial
        """
        self.setValidator(QtGui.QIntValidator(self))
        self.setAlignment(QtCore.Qt.AlignRight)
        self.ponInt( valor )
        return self

    def ponInt( self, valor ) :
        """
        Pone el número entero en el campo
        """
        self.ponTexto( str(valor) )
        return self

    def textoInt(self) :
        """
        Recupera el entero del campo.
        """
        txt = str(self.text( ))
        return int(txt) if txt else 0

#==========================================================================================================================================
class SB( QtGui.QSpinBox ) :
    """
    SpinBox: Entrada de números enteros, con control de incremento o reducción
    """
    def __init__( self, valor, desde, hasta ) :
        """
        @param valor: valor inicial
        @param desde: límite inferior
        @param hasta: límite superior
        """
        QtGui.QSpinBox.__init__(self)
        self.setRange(desde, hasta)
        self.setSingleStep(1)
        self.setValue(int(valor))

    def tamMaximo( self, maxTam ) :
        """
        Tamaño máximo del campo en pixeles
        """
        self.setFixedWidth( maxTam )
        return self

    def valor( self ) :
        return self.value()

    def ponValor( self, valor ) :
        self.setValue(int(valor))

#==========================================================================================================================================
class CB( QtGui.QComboBox ) :
    """
    ComboBox : entrada de una lista de opciones
    """
    def __init__( self, liOpciones, valorInicial ) :
        """
        @param liOpciones: lista de (etiqueta,clave)
        @param valorInicial: valor inicial
        """
        QtGui.QComboBox.__init__( self )
        self.rehacer( liOpciones, valorInicial )

        self.liOpciones = liOpciones

    def resultado( self ) :
        """
        Devuelve la clave de la opción elegida
        """
        return self.itemData(self.currentIndex())

    #--------------------------------------------------------------------------
    def ponFuente( self, f ) :
        """
        Pone el tipo de letra f
        """
        self.setFont( f )
        return self

    def rehacer( self, liOpciones, valorInicial ) :
        self.clear()
        for n, (etiqueta,clave) in enumerate(liOpciones) :
            self.addItem( etiqueta, clave )
            if clave == valorInicial :
                self.setCurrentIndex( n )

    def ponValor( self, valor ) :
        for n, (etiqueta,clave) in enumerate(self.liOpciones) :
            if clave == valor :
                self.setCurrentIndex( n )
                break

    #--------------------------------------------------------------------------
    def ponAncho( self, tam ) :
        r = self.geometry()
        r.setWidth( tam )
        self.setGeometry( r )
        return self

    #--------------------------------------------------------------------------
    def ponAnchoMinimo( self ) :
        self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
        return self

    #--------------------------------------------------------------------------
    def capturaCambiado( self, owner, rutina ) :
        owner.connect( self, QtCore.SIGNAL("currentIndexChanged(int)"), rutina )
        return self
#==========================================================================================================================================
class CHB( QtGui.QCheckBox ) :
    """
    CheckBox : entrada de una campo seleccionable
    """
    def __init__( self, etiqueta, valorInicial ) :
        """
        @param etiqueta: rótulo mostrado
        @param valorInicial: valor inicial : True/False
        """
        QtGui.QCheckBox.__init__( self, etiqueta )
        self.setChecked( valorInicial )
    #--------------------------------------------------------------------------
    def ponValor(self, si) :
        self.setChecked( si )
        return self
    #--------------------------------------------------------------------------
    def valor(self) :
        return self.isChecked()
    #--------------------------------------------------------------------------
    def ponFuente( self, f ) :
        """
        Pone el tipo de letra f
        """
        self.setFont( f )
        return self
    #--------------------------------------------------------------------------
    def capturaCambiado( self, owner, rutina ) :
        owner.connect( self, QtCore.SIGNAL( "clicked()" ), rutina)
        return self

#==========================================================================================================================================
class LB(QtGui.QLabel):
    """
    Etiquetas de texto.
    """

    #--------------------------------------------------------------------------
    def __init__(self, texto = None):
        """
        @param texto: texto inicial.
        """
        if texto :
            QtGui.QLabel.__init__(self, texto)
        else :
            QtGui.QLabel.__init__(self)

        self.setOpenExternalLinks( True )

    #--------------------------------------------------------------------------
    def ponTexto(self, texto) :
        """
        Asigna un texto a la etiqueta.
        """
        self.setText( texto )

    #--------------------------------------------------------------------------
    def texto(self) :
        return str(self.text())

    #--------------------------------------------------------------------------
    def ponFuente(self, f) :
        self.setFont( f )
        return self

    #--------------------------------------------------------------------------
    def alinCentrado( self ) :
        """
        Alinea al centro.
        """
        self.setAlignment( QtCore.Qt.AlignCenter )
        return self

    #--------------------------------------------------------------------------
    def alinDerecha( self ) :
        """
        Alinea a la derecha.
        """
        self.setAlignment( QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter )
        return self

    #--------------------------------------------------------------------------
    def anchoMaximo( self, tam ) :
        self.setMaximumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def anchoFijo( self, tam ) :
        """
        Ancho fijo del campo.
        """
        self.setFixedWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def anchoMinimo( self, tam ) :
        """
        Ancho mínimo del campo.
        """
        self.setMinimumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def altoFijo( self, tam ) :
        """
        Alto fijo del campo.
        """
        self.setFixedHeight( tam )
        return self

    #--------------------------------------------------------------------------
    def ponImagen( self, pm ) :
        self.setPixmap( pm )
        return self

    #--------------------------------------------------------------------------
    def ponFondo( self, color ) :
        return self.ponFondoN( color.name() )

    #--------------------------------------------------------------------------
    def ponFondoN( self, color ) :
        self.setStyleSheet("QWidget { background-color: %s }" % color)
        return self

    #--------------------------------------------------------------------------
    def ponColor( self, color ) :
        return self.ponColorN( color.name() )

    #--------------------------------------------------------------------------
    def ponColorN( self, color ) :
        self.setStyleSheet("QWidget { color: %s }" % color)
        return self

    #--------------------------------------------------------------------------
    def ponColorFondoN( self, color, fondo ) :
        self.setStyleSheet("QWidget { color: %s; background-color: %s}" % (color,fondo) )
        return self

    #--------------------------------------------------------------------------
    def ponWrap( self ) :
        self.setWordWrap(True)
        return self

    #--------------------------------------------------------------------------
    def ponAncho( self, tam ) :
        r = self.geometry()
        r.setWidth( tam )
        self.setGeometry( r )
        return self
#------------------------------------------------------------------------------------------------------------------------------------------
def LB2P( texto ) :
    return LB( texto + " : " )
#==========================================================================================================================================
class PB(QtGui.QPushButton):
    """
    Botón.
    """

    #--------------------------------------------------------------------------
    def __init__(self, parent, texto, rutina = None, plano = True ):
        """
        @param parent: ventana propietaria, necesario para conectar una rutina.
        @param texto: etiqueta inicial.
        @param rutina: rutina a la que se conecta el botón.
        """
        QtGui.QPushButton.__init__(self, texto, None)
        self.wParent = parent
        self.setFlat( plano )
        if rutina :
            self.conectar( rutina )

    #--------------------------------------------------------------------------
    def ponIcono(self, icono, tamIcon = 16) :

        self.setIcon( icono )
        self.setIconSize( QtCore.QSize( tamIcon, tamIcon ) )
        return self
    #--------------------------------------------------------------------------
    def ponFuente(self, f) :
        self.setFont( f )
        return self
    #--------------------------------------------------------------------------
    def anchoFijo( self, tam ) :
        """
        Ancho fijo del campo.
        """
        self.setFixedWidth( tam )
        return self
    #--------------------------------------------------------------------------
    def altoFijo( self, tam ) :
        """
        Alto fijo del campo.
        """
        self.setFixedHeight( tam )
        return self
    #--------------------------------------------------------------------------
    def cuadrado( self, tam ) :
        self.setFixedSize( tam, tam )
        return self

    #--------------------------------------------------------------------------
    def anchoMinimo( self, tam ) :
        """
        Ancho mínimo del campo.
        """
        self.setMinimumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def conectar( self, rutina ) :
        """
        Se indica la rutina asociada cuando se presiona.
        """
        self.wParent.connect( self, QtCore.SIGNAL("clicked()"), rutina )
        return self

    #--------------------------------------------------------------------------
    def ponFondo( self, txtFondo ) :
        self.setStyleSheet("QWidget { background: %s }"%txtFondo)
        return self

    #--------------------------------------------------------------------------
    def ponFondoN( self, ncolor ) :
        self.setStyleSheet("QWidget { background-color: %d }" % ncolor)
        return self

    #--------------------------------------------------------------------------
    def ponPlano( self, siPlano ) :
        self.setFlat( siPlano )
        return self

    #--------------------------------------------------------------------------
    def ponToolTip( self, txt ) :
        self.setToolTip( txt )
        return self
    #--------------------------------------------------------------------------
    def ponTexto( self, txt ) :
        self.setText( txt )

#==========================================================================================================================================
class RB(QtGui.QRadioButton) :
    """
    RadioButton: lista de alternativas
    """
    #--------------------------------------------------------------------------
    def __init__(self, wParent, texto, rutina = None ):
        QtGui.QRadioButton.__init__( self, texto )
        if rutina :
            wParent.connect( self, QtCore.SIGNAL("clicked()"), rutina )
    #--------------------------------------------------------------------------
    def activa(self, siActivar = True ) :
        self.setChecked( siActivar )
        return self

#==========================================================================================================================================
class GB(QtGui.QGroupBox):
    """
    GroupBox: Recuadro para agrupamiento de controles
    """

    #--------------------------------------------------------------------------
    def __init__(self, wParent, texto, layout ):
        QtGui.QGroupBox.__init__(self, texto)
        self.setLayout(layout)
        self.wParent = wParent

    #--------------------------------------------------------------------------
    def ponFuente(self, f) :
        self.setFont( f )
        return self

    #--------------------------------------------------------------------------
    def alinCentrado(self) :
        self.setAlignment( QtCore.Qt.AlignHCenter )
        return self

    #--------------------------------------------------------------------------
    def conectar( self, rutina ) :
        """
        Se indica la rutina asociada cuando se presiona.
        """
        self.setCheckable( True )
        self.setChecked( False )
        self.wParent.connect( self, QtCore.SIGNAL("clicked()"), rutina )
        return self

    #--------------------------------------------------------------------------
    def ponTexto( self, texto ) :
        self.setTitle( texto )
        return self

#==========================================================================================================================================
class EM(QtGui.QTextEdit):
    """
    Control de entrada de texto en varias líneas.
    """

    #--------------------------------------------------------------------------
    def __init__(self, parent, texto = None, siHTML = True ):
        """
        @param texto: texto inicial.
        """
        QtGui.QTextEdit.__init__(self, parent)
        self.parent = parent

        self.menu = None # menú de contexto
        self.rutinaDobleClick = None

        self.setAcceptRichText( siHTML )

        if texto :
            if siHTML :
                self.setText( texto )
            else :
                self.insertPlainText( texto )

    #--------------------------------------------------------------------------
    def ponHtml(self, texto) :
        """
        Pone el texto en el campo.
        """
        self.setHtml( texto )
        return self

    #--------------------------------------------------------------------------
    def insertarHtml(self, texto) :
        """
        Inserta un texto en la posición del cursor.
        """
        self.insertHtml( texto )
        return self

    #--------------------------------------------------------------------------
    def insertarTexto(self, texto) :
        """
        Inserta un texto en la posición del cursor.
        """
        self.insertPlainText( texto )
        return self

    #--------------------------------------------------------------------------
    def soloLectura(self) :
        self.setReadOnly( True )
        return self

    #--------------------------------------------------------------------------
    def texto(self) :
        """
        Recupera el texto del campo.
        """
        return str(self.toPlainText( ))

    #--------------------------------------------------------------------------
    def ponTexto(self, txt) :
        """
        texto del campo.
        """
        self.setText("")
        self.insertarTexto( txt )

    #--------------------------------------------------------------------------
    def html(self) :
        """
        Recupera el texto del campo.
        """
        return str(self.toHtml( ))

    #--------------------------------------------------------------------------
    def ponAncho( self, tam ) :
        r = self.geometry()
        r.setWidth( tam )
        self.setGeometry( r )
        return self

    #--------------------------------------------------------------------------
    def anchoMinimo( self, tam ) :
        """
        Ancho mínimo del campo.
        """
        self.setMinimumWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def altoMinimo( self, tam ) :
        """
        Alto mínimo del campo.
        """
        self.setMinimumHeight( tam )
        return self

    #--------------------------------------------------------------------------
    def altoFijo( self, tam ) :
        """
        Alto mínimo del campo.
        """
        self.setFixedHeight( tam )
        return self

    #--------------------------------------------------------------------------
    def anchoFijo( self, tam ) :
        """
        Ancho fijo del campo.
        """
        self.setFixedWidth( tam )
        return self

    #--------------------------------------------------------------------------
    def ponFuente( self, f ) :
        self.setFont( f )
        return self

    #--------------------------------------------------------------------------
    def ponWrap( self, siPoner ) :
        self.setWordWrapMode(QtGui.QTextOption.WordWrap if siPoner else QtGui.QTextOption.NoWrap)
        return self

    #--------------------------------------------------------------------------
    def capturaCambios( self, rutina ) :
        self.parent.connect( self, QtCore.SIGNAL( "textChanged()" ), rutina )
        return self

    #--------------------------------------------------------------------------
    def capturaDobleClick( self, rutina ) :
        self.rutinaDobleClick = rutina
        return self

    #--------------------------------------------------------------------------
    def mouseDoubleClickEvent( self, event ) :
        if self.rutinaDobleClick :
            self.rutinaDobleClick( event )

    #--------------------------------------------------------------------------
    def posicion( self ) :
        return self.textCursor().position()

#==========================================================================================================================================
class LMenu(QtGui.QMenu) :
    """
    Menu popup.

    Ejemplo::

        menu = Controles.LMenu()

        menu.opcion( "op1", "Primera opcion", icono )
        menu.separador()
        menu.opcion( "op2", "Segunda opcion", icono1 )
        menu.separador()

        menu1 = menu.submenu( "Submenu", icono2 )
        menu1.opcion( "op3_1", "opcion 1", icono3 )
        menu1.separador()
        menu1.opcion( "op3_2", "opcion 2", icono3 )
        menu1.separador()

        resp = menu.lanza()

        if resp :
            if resp == "op1" :
                ..........

            elif resp == "op2" :
                ................
    """
    #--------------------------------------------------------------------------
    def __init__( self, titulo = None, icono = None, siDeshabilitado = False, owner = None, puntos = None, siBold = True ) :

        QtGui.QMenu.__init__(self,owner)

        if titulo :
            self.setTitle( titulo )
        if icono :
            self.setIcon( icono )
        if siDeshabilitado :
            self.setDisabled( True )

        if puntos :
            tl = TipoLetra( puntos=puntos, peso = 75 ) if siBold else TipoLetra( puntos=puntos )
            self.setFont( tl )

    #--------------------------------------------------------------------------
    def ponFuente(self, f) :
        self.setFont( f )
        return self

    #--------------------------------------------------------------------------
    def opcion( self, clave, rotulo, icono = None, siDeshabilitado = False, tipoLetra = None ) :
        if icono :
            accion = QtGui.QAction( icono, rotulo, self )
        else :
            accion = QtGui.QAction( rotulo, self )
        accion.clave = clave
        if siDeshabilitado :
            accion.setDisabled( True )
        if tipoLetra :
            accion.setFont( tipoLetra )
        self.addAction( accion )
        return accion

    #--------------------------------------------------------------------------
    def submenu( self, rotulo, icono = None, siDeshabilitado = False ) :
        menu = LMenu( rotulo, icono, siDeshabilitado, owner = self )
        menu.setFont( self.font() )
        self.addMenu( menu )
        return menu

    #--------------------------------------------------------------------------
    def mousePressEvent( self, event ) :
        self.siIzq = event.button() == QtCore.Qt.LeftButton
        self.siDer = event.button() == QtCore.Qt.RightButton
        resp = QtGui.QMenu.mousePressEvent(self,event)
        return resp

    #--------------------------------------------------------------------------
    def separador( self ) :
        self.addSeparator( )

    #--------------------------------------------------------------------------
    def lanza( self ) :
        resp = self.exec_(QtGui.QCursor.pos())
        if resp :
            return resp.clave
        else :
            return None

#==========================================================================================================================================
class TB( QtGui.QToolBar ) :
    """
    Crea una barra de tareas simple.

    @param liAcciones: lista de acciones, en forma de tupla = titulo, icono, clave
    @param siTexto: si muestra texto
    @param tamIcon: tamaño del icono
    @param rutina: rutina que se llama al pulsar una opción. Por defecto será parent.procesarTB().
        Y la clave enviada se obtiene de self.sender().clave
    """

    def __init__( self, parent, liAcciones, siTexto = True, tamIcon=32, rutina = None, puntos = None ) :

        QtGui.QToolBar.__init__(self, "BASICO", None)

        self.setIconSize( QtCore.QSize( tamIcon, tamIcon ) )

        if rutina is None :
            rutina = parent.procesarTB

        if siTexto :
            self.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)

        if puntos :
            f = TipoLetra( puntos=puntos )

        self.dicTB = {}
        lista = []
        for datos in liAcciones :
            if datos :
                titulo, icono, clave = datos
                accion = QtGui.QAction( titulo, parent)
                accion.setIcon( icono )
                accion.setIconText( titulo )
                parent.connect( accion, QtCore.SIGNAL("triggered()"), rutina )
                accion.clave = clave
                if puntos :
                    accion.setFont( f )
                lista.append( accion )
                self.addAction( accion )
                self.dicTB[clave] = accion
            else :
                self.addSeparator(  )
        self.liAcciones = lista

#==========================================================================================================================================
class TipoLetra(QtGui.QFont) :
    def __init__( self, nombre="", puntos=8, peso=50, siCursiva=False, siSubrayado=False, siTachado=False, txt = None ) :
        QtGui.QFont.__init__(self)
        if txt is None :
            cursiva = 1 if siCursiva else 0
            subrayado = 1 if siSubrayado else 0
            tachado = 1 if siTachado else 0
            txt = "%s,%d,-1,5,%d,%d,%d,%d,0,0"%( nombre, puntos, peso, cursiva, subrayado, tachado )
        self.fromString(txt)
