# GNU Enterprise Forms - GTK UI Driver - Image widget
#
# Copyright 2001-2009 Free Software Foundation
#
# This file is part of GNU Enterprise
#
# GNU Enterprise 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, or (at your option) any later version.
#
# GNU Enterprise 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 program; see the file COPYING. If not,
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# $Id: image.py 9956 2009-10-11 18:54:57Z reinhard $

import gtk
import StringIO
try:
  from PIL import Image as PILImage
except:
  PILImage = None

from gnue.forms.uidrivers.gtk2.widgets._base import UIHelper

# =============================================================================
# This class implements an image widget for GTK2 driver
# =============================================================================

class UIImage(UIHelper):

  # ---------------------------------------------------------------------------
  # Create the gtk-widget
  # ---------------------------------------------------------------------------

  def _create_widget (self, event, spacer):
    image = gtk.Image ()
    
    self.pane = gtk.ScrolledWindow ()
    self.pane.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    self.pane.set_shadow_type (gtk.SHADOW_NONE)

    self.pane.add_with_viewport (image)
    self.pane.set_size_request (self.itemWidth, self.itemHeight)

    event.container.put (self.pane, self.itemX, self.itemY)
    
    return image

    
  # -------------------------------------------------------------------------
  # Set "editable" status for this widget
  # -------------------------------------------------------------------------

  def _ui_set_editable_(self, index, editable):

    pass


  # ---------------------------------------------------------------------------
  # Set the widget's PIL
  # ---------------------------------------------------------------------------

  def _ui_set_value_(self, index, value):
    if PILImage is None:
      return

    widget = self.widgets [index]

    imgx, imgy = value.size
    scrx, scry = self.pane.size_request ()

    # Subtract the surrounding frame
    scrx      -= 4
    scry      -= 4

    scalex = scaley = 1

    fit = self._gfObject.fit

    if fit == "auto":
      if float (scrx) / imgx < float (scry) / imgy:
        fit = "width"
      else:
        fit = "height"

    if fit == "width":
      scalex = scaley = float (scrx) / imgx

    elif fit == "height":
      scalex = scaley = float (scry) / imgy

    elif fit == "both":
      scalex = float (scrx) / imgx
      scaley = float (scry) / imgy

    if scalex != 1 or scaley != 1:
      nWidth  = abs (int (imgx * scalex))
      nHeight = abs (int (imgy * scaley))
      value = value.resize ((nWidth, nHeight), PILImage.BICUBIC)
    
    widget.set_from_pixbuf (self.__imageToGdkPixbuf (value))
    

  # ---------------------------------------------------------------------------
  # Convert a PIL image into a Gdk.Pixbuf
  # ---------------------------------------------------------------------------

  def __imageToGdkPixbuf (self, pilImage):
    file = StringIO.StringIO ()
    pilImage.save (file, 'ppm')
    contents = file.getvalue()
    file.close ()
    loader = gtk.gdk.PixbufLoader ('pnm')
    loader.write (contents, len (contents))
    pixbuf = loader.get_pixbuf ()
    loader.close ()
    return pixbuf


# -----------------------------------------------------------------------------
# Configuration data
# -----------------------------------------------------------------------------

configuration = {
  'baseClass'  : UIImage,
  'provides'   : 'GFImage',
  'container'  : 0,
}
