## dpiDialog.py - UI code for configuring DPI
## Copyright (C) 2001-2003 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., 675 Mass Ave, Cambridge, MA 02139, USA.

import math
import gtk
from rhpl.translate import _, N_,textdomain
from rhpl.xhwstate import *

TRUE = 1
FALSE = 0

class DPIDialog:
    unit_inch = 0
    unit_millimeter = 1
    
    def __init__(self, xml, monitor):
        self.xml = xml
        self.monitor = monitor

        self.unit = self.unit_millimeter
        self.resolution = None
        
        dialog = xml.get_widget("dpi_dialog")
        dialog.set_transient_for(xml.get_widget("display_dialog"))
        dialog.set_modal(TRUE)
        
        self.width_spin = xml.get_widget("dpi_width_spin")
        self.height_spin = xml.get_widget("dpi_height_spin")
        self.unit_menu = xml.get_widget("dpi_unit_menu")
        self.dpi_label = xml.get_widget("dpi_resolution_label")

        # Initial unit is millimeter
        self.width_spin.set_digits(0)
        self.height_spin.set_digits(0)
            
        self.unit_menu.connect("changed", self.units_changed)
        self.width_spin.connect("value_changed", self.value_changed)
        self.height_spin.connect("value_changed", self.value_changed)

        button = xml.get_widget("dpi_probe_button")
        button.connect("clicked", self.probe_monitor)
        if monitor.getMonitorPhysicalWidth(TRUE) == 0 or monitor.getMonitorPhysicalHeight(TRUE) == 0:
            button.set_sensitive(FALSE)

    def probe_monitor(self, widget):
        self.set_value(self.monitor.getMonitorPhysicalWidth(TRUE),
                       self.monitor.getMonitorPhysicalHeight(TRUE))

    def units_changed(self, widget):
        (w, h) = self.get_value()
        self.unit = widget.get_history()
        self.set_value(w,h)
        if self.unit == self.unit_inch:
            self.width_spin.set_digits(2)
            self.height_spin.set_digits(2)
        else:
            self.width_spin.set_digits(0)
            self.height_spin.set_digits(0)
            

    def update_dpi_label(self):
        (w,h) = self.get_value()
        if self.resolution:
            self.dpi_label.set_text(_("Current resolution: ") + dpi_string(self.resolution, w, h))

    def value_changed(self, widget):
        self.update_dpi_label()
        
    def set_value(self, w, h):
        if self.unit == self.unit_inch:
            self.width_spin.set_value(w / 25.4)
            self.height_spin.set_value(h / 25.4)
            self.unit_menu.set_history(0)
        else:
            self.width_spin.set_value(w)
            self.height_spin.set_value(h)
            self.unit_menu.set_history(1)
        
    def get_value(self):
        if self.unit == self.unit_inch:
            w = self.width_spin.get_value() * 25.4
            h = self.height_spin.get_value() * 25.4
        else:
            w = self.width_spin.get_value()
            h = self.height_spin.get_value()
        w = math.floor(w+0.5)
        h = math.floor(h+0.5)
        return (w, h)
        
    def hydrate(self, state):
        (w, h) = state.get_physical_size_or_probed()
        self.set_value (w, h)
        self.resolution = state.get_resolution()
        self.update_dpi_label()
    
    def dehydrate(self, state):
        (realw, realh) = state.get_physical_size()
        probed = state.get_physical_size_or_probed()
        inputed = self.get_value()
        # If the size is currently unspecified, and the user
        # didnt change from the probed size, keep it unspecified
        if (realw == 0 or realh == 0) and probed == inputed:
            return
        state.set_physical_size(inputed[0], inputed[1])

    def run(self):
        dialog = self.xml.get_widget("dpi_dialog")
        dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        dialog.present()
        while 1:
            res = dialog.run()
            if res != gtk.RESPONSE_OK:
                dialog.hide()
                return FALSE

            break
        
        dialog.hide()
        return TRUE

