# GNU Enterprise Forms - GTK UI Driver - wrapper for form wigets
#
# 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: wrappers.py 9956 2009-10-11 18:54:57Z reinhard $

import gtk

from gnue.common import events

# =============================================================================
# Constants
# =============================================================================

_tabStyles = {'left'  : gtk.POS_LEFT,
              'right' : gtk.POS_RIGHT,
              'bottom': gtk.POS_BOTTOM,
              'top'   : gtk.POS_TOP}

# =============================================================================
# Base class for scrollable pages
# =============================================================================

class ScrollableWrapper (gtk.ScrolledWindow):

  # ---------------------------------------------------------------------------
  # Constructor
  # ---------------------------------------------------------------------------

  def __init__(self, uiform):
    self.uiform = uiform
    self.form   = uiform._form
    self.frame  = uiform.containerFrame
    self.margin = 2
    gtk.ScrolledWindow.__init__ (self)
    self.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    self.frame.add (self)

    formWidth        = int (self.form._layout.Char__width)
    formHeight       = int (self.form._layout.Char__height)

    self.layoutXSize = formWidth  * uiform._uiDriver.widgetWidth
    self.layoutYSize = formHeight * uiform._uiDriver.widgetHeight

    self.halfX = int (0.5 * uiform._uiDriver.widgetWidth)
    self.halfY = int (0.5 * uiform._uiDriver.widgetHeight)

    self.layoutXSize = formWidth  * uiform._uiDriver.widgetWidth
    self.layoutYSize = formHeight * uiform._uiDriver.widgetHeight
    
    self._fitted   = 0
    self._pageList = []

  # ---------------------------------------------------------------------------
  # Final actions on a wrapper
  # ---------------------------------------------------------------------------

  def finalize (self):
    pass

# =============================================================================
# Single page forms
# =============================================================================

class PlainWrapper (ScrollableWrapper):

  # ---------------------------------------------------------------------------
  # Constructor
  # ---------------------------------------------------------------------------

  def __init__ (self, *args, **parms):
    ScrollableWrapper.__init__ (self, *args, **parms)
    self.pane = gtk.Fixed ()
    self.add_with_viewport (self.pane)
    # self.set_size_request (self.layoutXSize, self.layoutYSize)
    
  # ---------------------------------------------------------------------------
  # Finalize the wrapper
  # ---------------------------------------------------------------------------

  def finalize (self):
    self.pane.set_size_request (self.layoutXSize, self.layoutYSize)
    self.set_size_request (self.layoutXSize + self.halfX,
                           self.layoutYSize + self.halfY)

  # ---------------------------------------------------------------------------
  # Create a new page
  # ---------------------------------------------------------------------------

  def createPage (self, gfObject):
    newWidget = gtk.Fixed ()
    self.pane.add (newWidget)

    # Only show first page
    if len (self._pageList) < 1:
      newWidget.show_all ()
      
    self._pageList.append (newWidget)
    return newWidget

  
  # ---------------------------------------------------------------------------
  # Activate a given page
  # ---------------------------------------------------------------------------

  def setPage (self, page):
    for p in self._pageList:
      if p != page:
        p.show_all ()
      else:
        p.hide ()


# =============================================================================
# This class implements paged forms using a gtk.Notebook as baseclass
# =============================================================================

class TabbedWrapper (gtk.Notebook):

  # ---------------------------------------------------------------------------
  # Constructor
  # ---------------------------------------------------------------------------

  def __init__ (self, uiform):
    self.uiform = uiform
    self.frame  = frame = uiform.containerFrame
    self.pane   = self
    self.margin = 2
    gtk.Notebook.__init__ (self)

    try:
      tabstyle = _tabStyles [self.form._layout.tabbed]
      self.set_tab_pos (tabstyle)
    except:
      pass

    self.set_scrollable (True)

    self.connect('switch-page', self.__on_switch_page)
    self.connect('focus-in-event', self.__on_focus_in_event)

    self.frame.add (self)

    self.form  = form = uiform._form
    formWidth  = int (form._layout.Char__width)
    formHeight = int (form._layout.Char__height)

    # Since we have additional tabs, we stretch the formheight
    self.layoutXSize = formWidth  * uiform._uiDriver.widgetWidth
    self.layoutYSize = int ((formHeight + 1.5) * uiform._uiDriver.widgetHeight)

    self._oldpage  = 0
    self._pageList = []

    self.__notebookLoopTrap = 0


  # ---------------------------------------------------------------------------
  # Create a new page and append it to the notebook
  # ---------------------------------------------------------------------------

  def createPage (self, gfObject):

    assert gDebug (6, "createPage %s for %s" % (self, gfObject))
    newWidget = gtk.Fixed ()
    swin = gtk.ScrolledWindow ()

    swin.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    swin.add_with_viewport (newWidget)
    text = "%s" % (gfObject.caption or gfObject.name)
    self.append_page (swin, gtk.Label (text.encode ('utf-8')))

    self._pageList.append (newWidget)
    newWidget.show ()

    return newWidget


  # ---------------------------------------------------------------------------
  # Finalize the widget
  # ---------------------------------------------------------------------------

  def finalize (self):
    self.pane.set_size_request (self.layoutXSize, self.layoutYSize)
    

  # ---------------------------------------------------------------------------
  # Event handlers
  # ---------------------------------------------------------------------------

  def __on_switch_page(self, notebook, notebookpage, page_number):

    assert gDebug(6, "switch-page %r %r %r -> %r" \
            % (notebook, notebookpage, self._oldpage, page_number))
    if self._oldpage != page_number:
        self.form._event_page_changed(page_number)
        self._oldpage = page_number

  # ---------------------------------------------------------------------------

  def __on_focus_in_event(self, widget, event):

      assert gDebug(6, "focus-in-event %r %r" % (widget, event))
      self.form._event_focus_changed(None, 0)

  # ---------------------------------------------------------------------------
  # Activate a given page in the notebook
  # ---------------------------------------------------------------------------

  def setPage (self, page):
    assert gDebug (6, "SET-PAGE %s to %s" % (self, page))

    swin = page.get_parent ().get_parent ()
    pageNum = self.page_num (swin)
    self._oldpage = pageNum
    self.set_current_page (pageNum)

