# GNU Enterprise Forms - QT3 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 qt
import cStringIO

try:
  from PIL import Image as PILImage

except:
  PILImage = None

from gnue.common.definitions import GParser
from gnue.forms.uidrivers.qt3.widgets import _base

# =============================================================================
# Exceptions
# =============================================================================

class MissingSizeError(GParser.MarkupError):
    """ Image has no size given """
    def __init__(self, image):
        msg = u_("Image '%(name)s' is missing one of Sizer:width or "
                 "Sizer:height") % {'name': image.name}
        GParser.MarkupError.__init__(self, msg, image._url, image._lineNumber)


# =============================================================================
# Wrap an UI layer around a wx image
# =============================================================================

class UIImage (_base.UIHelper):
    """
    Creates a single instance of an image.
    """

    # ------------------------------------------------------------------------
    # Create an image widget
    # ------------------------------------------------------------------------

    def _create_widget_ (self, event, spacer):
        """
        Creates a new StaticBitmap widget.
        """

        parent = event.container

        (min_w, min_h) = self.get_default_size()
        self.widget = qt.QScrollView(parent)
        self.widget.setMinimumSize(min_w, min_h)
        
        image = qt.QLabel(self.widget)
        self.widget.addChild(image)
        
        self.getParent().add_widgets(self, spacer)

        return image


    # -------------------------------------------------------------------------
    # Get the default size for the image
    # -------------------------------------------------------------------------

    def get_default_size(self):

        if self.managed:
            width = int(getattr(self._gfObject, 'Sizer__width', -1))
            height = int(getattr(self._gfObject, 'Sizer__height', -1))
            if width == -1 or height == -1:
                raise MissingSizeError(self._gfObject)
        else:
            width = self._uiDriver.cell_width * self.chr_w
            height = self._uiDriver.cell_height * self.chr_h

        return (width, height)


    # -------------------------------------------------------------------------
    # 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):
        """
        Loads an image.
        """

        if PILImage is None:
            return

        widget = self.widgets [index]
        scrx, scry = self.get_default_size()
        imgx, imgy = value.size

        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
        else:
            self.widget.resizeContents(imgx, imgy)
        
        if scalex != 1 or scaley != 1:
            value = value.resize ((abs(int(imgx * scalex)),
                abs(int(imgy * scaley))), PILImage.BICUBIC)

        # Convert the PIL Image to a QPixmap
        # TODO: find a better way than using StringIO
        # Note: the PIL 1.1.6 release contains ImageQT
        #       which allows direct convertion into qt4
        #       compatible objects via ImageQt.ImageQt(PILimage)
        #
        f = cStringIO.StringIO()
        value.save(f, 'PNG')
        pxm = qt.QPixmap()
        pxm.loadFromData(f.getvalue())
        widget.setPixmap(pxm)
        pxmSize = pxm.size()

# =============================================================================
# Configuration data
# =============================================================================

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