# -*- coding: utf-8 -*-

# Copyright (c) 2004 - 2006 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a zoom dialog for a graphics canvas.
"""

import sys
from math import pow
from types import IntType

from qt import *

class DoubleSpinBox(QSpinBox):
    """
    Class implementing a spinbox for double values.
    """
    def __init__(self, parent = None, name = None):
        """
        Constructor
        
        @param parent parent widget (QWidget)
        @param name name of this widget (QString or string)
        """
        QSpinBox.__init__(self, parent, name)
        
        self.factor = 10
        dv = QDoubleValidator(self)
        dv.setDecimals(1)
        self.setValidator(dv)
        
    def setMaxValue(self, value):
        """
        Method to set the maximum allowed values.
        
        @param value maximum value (float)
        """
        QSpinBox.setMaxValue(self, int(self.factor * value))
        self.validator().setTop(value)
        
    def setMinValue(self, value):
        """
        Method to set the minimum allowed values.
        
        @param value minimum value (float)
        """
        QSpinBox.setMinValue(self, int(self.factor * value))
        self.validator().setBottom(value)
        
    def mapValueToText(self, value):
        """
        Protected method to convert a value to displayable text.
        
        @param value value to be shown (integer)
        @return displayable text (string)
        """
        return "%d.%d" % (value / self.factor, value % self.factor)
        
    def mapTextToValue(self):
        """
        Protected method to convert displaid text to a value.
        
        @return converted value (integer)
        """
        return (int(self.factor * float(str(self.text()))), 1)
        
    def setValue(self, value):
        """
        Method to set the value.
        
        @param value value to be set (integer or float)
        """
        if type(value) == IntType:
            QSpinBox.setValue(self, value)
        else:
            QSpinBox.setValue(self, int(self.factor * value))
        
    def value(self):
        """
        Method to retrieve the current value.
        
        @return current value (float)
        """
        return float(QSpinBox.value(self)) / self.factor
        
    def setDecimals(self, decimals):
        """
        Method to set the number of decimals.
        
        @param decimals number of decimals to be shown
        """
        self.factor = pow(10, decimals)
    
class ZoomDialog(QDialog):
    """
    Class implementing a zoom dialog for a graphics canvas.
    """
    def __init__(self,zoom,parent = None,name = None,modal = 0,fl = 0):
        """
        Constructor
        
        @param zoom zoom factor to show in the spinbox (float)
        @param parent parent widget of this dialog (QWidget)
        @param name name of this dialog (string or QString)
        @param modal flag indicating a modal dialog
        @param fl window flags
        """
        QDialog.__init__(self,parent,name,modal,fl)

        if not name:
            self.setName("ZoomDialog")


        ZoomFormLayout = QVBoxLayout(self,6,6,"ZoomFormLayout")

        Layout3 = QHBoxLayout(None,0,6,"Layout3")

        self.zoomLabel = QLabel(self,"zoomLabel")
        Layout3.addWidget(self.zoomLabel)

        self.zoomSpinBox = DoubleSpinBox(self,"zoomSpinBox")
        self.zoomSpinBox.setMaxValue(1000.0)
        self.zoomSpinBox.setMinValue(0.1)
        self.zoomSpinBox.setValue(zoom)
        Layout3.addWidget(self.zoomSpinBox)
        ZoomFormLayout.addLayout(Layout3)

        Layout4 = QHBoxLayout(None,0,6,"Layout4")
        spacer = QSpacerItem(16,0,QSizePolicy.Expanding,QSizePolicy.Minimum)
        Layout4.addItem(spacer)

        self.zoomButton = QPushButton(self,"zoomButton")
        self.zoomButton.setDefault(1)
        Layout4.addWidget(self.zoomButton)

        self.cancelButton = QPushButton(self,"cancelButton")
        Layout4.addWidget(self.cancelButton)
        spacer_2 = QSpacerItem(16,0,QSizePolicy.Expanding,QSizePolicy.Minimum)
        Layout4.addItem(spacer_2)
        ZoomFormLayout.addLayout(Layout4)

        self.languageChange()

        self.resize(QSize(181,78).expandedTo(self.minimumSizeHint()))

        self.connect(self.zoomButton,SIGNAL("clicked()"),self,SLOT("accept()"))
        self.connect(self.cancelButton,SIGNAL("clicked()"),self,SLOT("reject()"))

        self.zoomLabel.setBuddy(self.zoomSpinBox)

    def languageChange(self):
        """
        Private method to show translated display strings.
        """
        self.setCaption(self.tr("Zoom"))
        self.zoomLabel.setText(self.tr("Zoom &Factor:"))
        QToolTip.add(self.zoomSpinBox,self.tr("Enter zoom factor"))
        self.zoomButton.setText(self.tr("&Zoom"))
        QToolTip.add(self.zoomButton,self.tr("Zoom to the entered factor"))
        self.cancelButton.setText(self.tr("&Cancel"))
        QToolTip.add(self.cancelButton,self.tr("Cancel the dialog"))

    def getZoomSize(self):
        """
        Public method to retrieve the zoom size.
        
        @return zoom size (double)
        """
        return self.zoomSpinBox.value()

if __name__ == "__main__":
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = ZoomDialog(1.0)
    a.setMainWidget(w)
    w.show()
    a.exec_loop()
