itrade_wxutil.py :  » Business-Application » iTrade » itrade » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » iTrade 
iTrade » itrade » itrade_wxutil.py
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# ============================================================================
# Project Name : iTrade
# Module Name  : itrade_wxutil.py
#
# Description: wxPython utilities, incl. matplotlib func support
#
# The Original Code is iTrade code (http://itrade.sourceforge.net).
#
# The Initial Developer of the Original Code is Gilles Dumortier.
#
# Portions created by the Initial Developer are Copyright (C) 2004-2008 the
# Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# 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 3 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; see http://www.gnu.org/licenses/gpl.html
#
# History       Rev   Description
# 2005-10-26    dgil  Wrote it from scratch
# ============================================================================

# ============================================================================
# Imports
# ============================================================================

# python system
import logging
import re
import string
from types import *
import operator

# itrade system
from itrade_logging import *
from itrade_local import message

# wxPython system
import itrade_wxversion
import wx
import wx.html
import wx.lib.wxpTag
import wxaddons.sized_controls as sc

# matplotlib helpers
from matplotlib.colors import colorConverter

# iTrade wxpython
from itrade_wxhtml import wxUrlClickHtmlWindow,EVT_HTML_URL_CLICK

# ============================================================================
# MatplotColorToRGB()
#
# convert a MatplotColor to a RGB tuple used by wxPython
#
#      b  : blue
#      g  : green
#      r  : red
#      c  : cyan
#      m  : magenta
#      y  : yellow
#      k  : black
#      w  : white
#
# For a greater range of colors, you have two options.  You can specify
# the color using an html hex string, as in
#
#     color = '#eeefff'
#
# or you can pass an R,G,B tuple, where each of R,G,B are in the range
# [0,1].
#
# Finally, legal html names for colors, like 'red', 'burlywood' and
# 'chartreuse' are supported.
#
# ============================================================================

def MatplotColorToRGB(colorname='k'):
    r,g,b = colorConverter.to_rgb(colorname)

    return wx.Colour(int(r*255),int(g*255),int(b*255))

# ============================================================================
# FontFromSize
#   1 : small
#   2 : regular
#   3 : big
#
# Porting note : adjust this function to the platform ?? __x
# ============================================================================

def FontFromSize(size):
    if size==2:
        return wx.Font(10, wx.SWISS , wx.NORMAL, wx.NORMAL)
    elif size==3:
        return wx.Font(12, wx.SWISS , wx.NORMAL, wx.NORMAL)
    else:
        return wx.Font(7, wx.SWISS , wx.NORMAL, wx.NORMAL)

# ============================================================================
# wx.MessageDialog()
#
#   parent          Parent window
#   msg             Message to show on the dialog
#   caption         The dialog caption
#   style           A dialog style (bitlist) containing flags chosen from :
#      wxOK                 Show an OK button.
#      wxCANCEL             Show a Cancel button.
#      wxYES_NO             Show Yes and No buttons.
#      wxYES_DEFAULT        Used with wxYES_NO, makes Yes button the default -
#                           which is the default behaviour.
#      wxNO_DEFAULT         Used with wxYES_NO, makes No button the default.
#      wxICON_EXCLAMATION   Shows an exclamation mark icon.
#      wxICON_HAND          Shows an error icon.
#      wxICON_ERROR         Shows an error icon - the same as wxICON_HAND.
#      wxICON_QUESTION      Shows a question mark icon.
#      wxICON_INFORMATION   Shows an information (i) icon.
#      wxSTAY_ON_TOP        The message box stays on top of all other window,
#                           even those of the other applications (Win only).
#   pos             Dialog position. Not Windows
#
# ============================================================================

def Button(label,id,makedefault=0):
    return [(label,id,makedefault)]

def OKButton(makedefault=1):
    return Button(message('ok'),`wx.ID_OK`,makedefault)

def CancelButton(makedefault=0):
    return Button(message('cancel'),`wx.ID_CANCEL`,makedefault)

def ApplyButton(makedefault=0):
    return Button(message('valid'),`wx.ID_APPLY`,makedefault)

def YesButton(makedefault=1):
    return Button(message('yes'),`wx.ID_YES`,makedefault)

def NoButton(makedefault=0):
    return Button(message('no'),`wx.ID_NO`,makedefault)

# ============================================================================
# generate HTML for buttons
# ============================================================================

def _tupn(tup,n):
    if type(tup) == TupleType:
        try:
            return tup[n]
        except IndexError:
            return None
    else:
        if n == 0:
            return tup
        else:
            return None

DefaultButtonString = '''\
<wxp class="%s" module="%s">
    <param name="label" value="%s">
    <param name="id"    value="%s">
</wxp>'''

class Default_wxButton(wx.Button):
    def __init__(self,*args,**kwargs):
        apply(wx.Button.__init__, (self,) + args,kwargs)
        self.SetDefault()

def HTMLforSingleButton(label,id=None,makedefault=0):
    if id is None:
        return label
    else:
        if makedefault == 1:
            defaultstring1 = "Default_wxButton"
            defaultstring2 = "itrade_wxutil"
        else:
            defaultstring1 = "Button"
            defaultstring2 = "wx"
        return DefaultButtonString % (defaultstring1,defaultstring2,label,id)

def HTMLforButtons (buttons,betweenbuttons=""):
    def rn(n):
        return lambda tup,n=n: _tupn(tup,n)
    return string.join (map (HTMLforSingleButton,map(rn(0),buttons),map(rn(1),buttons),map(rn(2),buttons)),betweenbuttons)

# ============================================================================
# HTMLDialog
#
# Adapted (by dgil) to iTrade from HTMLDialog.py (by Chris Fama)
#
#    use:
#        dlg = HTMLDialog(parent,OPTIONS)
#    [or
#        dlg = HTMLDialog(parent)
#        ...........
#        dlg.SetContents(OPTIONS)
#     ]
#        ......
#        dlg.ShowModal() **OR** dlg.Show()
#        ..........>
#        dlg.Destroy () # if modal...........
#
#        OPTIONS (with defaults) from
#                     name="",
#                     buttons=OKButton(makedefault=1),
#                     text="",
#                     namefmt="<h1>%s</h1>",
#                     caption=None,
#                     betweenbuttons="",
#                     size=None,
#                     defaultsize=(420,380),
#                     image=None,
#                     imagedir="",
#                     imageurl="",
#                     link_regexp=re.compile("</a>",re.IGNORECASE),
#                     bgcolor=None,
#                     fgcolor=None,
#                     boxcolor='#458154'
#
#    "text" is the HTML to display in the box
#
#    "buttons" is a sequence of -
#        ("label",*"id") specifications for buttons, or "HTML code".
#
#    e.g.,
#        HTMLDialog(.......,
#                   buttons=OKButton(makedefault=1) + \
#                           CancelButton () +\
#                           ApplyButton () +\
#                           [" or be <i>brave</i> and "] +\
#                           Button("Exit now",`exitID`),
#                   .........)
#    [this is equivalent to
#        HTMLDialog(.......,
#                   buttons=[("OK",`wxID_OK`,1),
#                            ("Cancel",`wxID_CANCEL),
#                            ("Apply",`wxID_APPLY`),
#                            " or be <i>brave</i> and ",
#                            ("Exit now",`exitID`)],
#                   .........)
#     .
#
#    "image", if specified, is the filename of an image file to be displayed
#    to the left of the name;
#    ***       wxImage_AddHandler(wxGIFHandler()) is called if needed;
#              other handlers MAY be necessary. ***
#
#    "boxcolor" is used for the interior colour of the box containing the name
#    or "image" image file.  Both of these, if specified, should be HTML colour
#    specifications [i.e., '#RRGGBB', where RR is the hexadecimal value of the
#    red component of the colour, etc.
#
#    If "size" is unspecified or None, the size of the dialog is chosen so
#    as to be as small as possible without needing a vertical scrollbar,
#    while having the same aspect ratio as the display (see wxDisplaySize);
#    if this is not possible, then "defaultsize" is used.
#
# ============================================================================

class HTMLDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 size=None,
                 defaultsize=(420, 380),
                 name="",
                 caption=None,
                 **kwargs):

        # be sure to have a caption
        if caption is None:
            caption = name
        kwargs['name'] = name

        # use defaultsize if no size
        if size is None:
            size = defaultsize
        else:
            kwargs['size'] = size
        kwargs['defaultsize'] = defaultsize

        # init
        wx.Dialog.__init__(self, parent, -1, caption, style = wx.TAB_TRAVERSAL | wx.DEFAULT_DIALOG_STYLE, size = size)

        # container
        self.m_html = wxUrlClickHtmlWindow(self, -1, style = wx.CLIP_CHILDREN | wx.html.HW_SCROLLBAR_NEVER | wx.TAB_TRAVERSAL)
        EVT_HTML_URL_CLICK(self.m_html, self.OnLinkClick)

        # set the content
        apply(self.SetContents,(),kwargs)

        # layout the content
        self.SetAutoLayout(True)

        lc = wx.LayoutConstraints()
        lc.top.SameAs(self, wx.Top, 5)
        lc.left.SameAs(self, wx.Left, 5)
        lc.bottom.SameAs(self, wx.Bottom, 5)
        lc.right.SameAs(self, wx.Right, 5)
        self.m_html.SetConstraints(lc)
        self.Layout()

        self.GetDefaultItem().SetFocus()

        # from wxWindows docs: This function (wxWindow::OnCharHook) is
        # only relevant to top-level windows (frames and dialogs), and
        # under Windows only. Under GTK the normal EVT_CHAR_ event has
        # the functionality, i.e. you can intercepts it and if you
        # don't call wxEvent::Skip the window won't get the event.

        if sys.platform not in ["windows","nt"]:
            wx.EVT_CHAR_HOOK(self,self.OnCharHook)
        else:
            wx.EVT_CHAR(self,self.OnCharHook)

    def OnLinkClick(self, event):
        clicked = event.linkinfo[0]
        self.gotoInternetUrl(clicked)

    def gotoInternetUrl(self, url):
        try:
            import webbrowser
        except ImportError:
            iTradeInformation(message('about_url') % url)
        else:
            webbrowser.open(url)

    def OnCharHook(self,event):
        if event.KeyCode in (wx.WXK_RETURN,wx.WXK_SPACE) :
            for id in (wx.ID_YES,wx.ID_NO,wx.ID_OK):
                wnd = self.m_html.FindWindowById(id)
                if wnd:
                    tlw = wx.GetTopLevelParent(wnd)
                    if tlw.GetDefaultItem()==wnd:
                        wnd.ProcessEvent(wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED,id))
                        break

        elif event.KeyCode == wx.WXK_ESCAPE:
            if self.m_html.FindWindowById(wx.ID_CANCEL):
                self.m_html.FindWindowById(wx.ID_CANCEL).ProcessEvent(wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED,wx.ID_CANCEL))
            else:
                if self.IsModal() == False:
                    self.Show(False)
                else:
                    self.EndModal(wx.ID_CANCEL)
        else:
            event.Skip()

    DefaultHTML = '''\
            <html>
            <body %s %s>
            <center>
            <table cellpadding="5" bgcolor="%s" width="100%%">
              <tr>
                <td align="left">
                %s
                %s
                </td>
              </tr>
            </table>
            <p>%s</p>
            </body>
            </html>
            '''

    ImageHTML='''\
          <a href="%s"><img src="%s" align=top alt="%s" border=0></a>&nbsp;
            '''

    def SetContents(self,
                    name="",
                    buttons=OKButton(makedefault=1),
                    text="",
                    namefmt="<h1>%s</h1>",
                    betweenbuttons="&nbsp;",
                    link_regexp=re.compile("</a>",re.IGNORECASE),
                    defaultsize=(420, 380),
                    image = None,
                    imagedir = "res",
                    imageurl = "",
                    size = None,
                    fgcolor = "#000000",
                    bgcolor = "#EEEEEE",
                    boxcolor= "#EEEEEE"):

        # always one button : OK
        if buttons is None:
            buttons = OKButton()

        # dialog name with format
        name = namefmt % name

        # some image ?
        if image:
            imstr1 = self.ImageHTML % (imageurl,os.path.join(imagedir,image),"['%s']" % image)
        else:
            imstr1 = ""

        # colors
        if fgcolor is not None:
            colourstring1 = 'fgcolor="%s"' % fgcolor
        else:
            colourstring1 = ""

        if bgcolor is not None:
            colourstring2 = 'bgcolor="%s"' % bgcolor
        else:
            colourstring2 = ""

        # buttons
        self.registerButtons(buttons)
        buttonstring = HTMLforButtons(buttons,betweenbuttons=betweenbuttons)

        # set final content
        self.theHTMLpage = (self.DefaultHTML
                            % (colourstring1,colourstring2,
                               boxcolor,
                               imstr1,
                               text,
                               buttonstring)
                             )

        self.m_html.SetPage(self.theHTMLpage)

        if size is None:
            w,h = defaultsize
        else:
            w,h = size

        c = self.m_html.GetInternalRepresentation()
        c.Layout(w-10)
        self.SetSize(wx.Size(c.GetWidth()+10,c.GetHeight()+35))

        # layout everything
        self.Layout()
        self.CentreOnParent(wx.BOTH)

    def registerButtons(self,buttons):
        for button in buttons:
            label,id,default = button
            wx.EVT_BUTTON(self, int(id), self.OnButton)

    def OnButton(self,event):
        if self.Validate() and self.TransferDataFromWindow():
            if self.IsModal():
                self.EndModal(event.GetId())
            else:
                self.SetReturnCode(event.GetId());
                self.Show(False)

# ============================================================================
# iTradeSizedDialog
# ============================================================================

class iTradeSizedDialog(sc.SizedDialog):
    def __init__(self, *args, **kwargs):
        # context help
        pre = wx.PreDialog()
        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
        pre.Create(*args, **kwargs)
        self.PostCreate(pre)

        self.borderLen = 12
        self.mainPanel = sc.SizedPanel(self, -1)

        mysizer = wx.BoxSizer(wx.VERTICAL)
        mysizer.Add(self.mainPanel, 1, wx.EXPAND | wx.ALL, self.GetDialogBorder())
        self.SetSizer(mysizer)

        self.SetAutoLayout(True)

# ============================================================================
# iTradeDialog()
#
#   style
#       wx.OK
#       or wx.YES_NO
#
#       wx.YES_DEFAULT
#       wx.NO_DEFAULT
#
#       wx.HELP
#
#       wx.CANCEL
#
#       wx.ICON_INFORMATION
#       or wx.ICON_ERROR
#       or wx.ICON_QUESTION
# ============================================================================

class iTradeDialog(iTradeSizedDialog):
    def __init__(self,parent,caption,text,size=(420, 380),style=wx.OK | wx.YES_DEFAULT):
        iTradeSizedDialog.__init__(self,parent,-1,caption,size,style=wx.DEFAULT_DIALOG_STYLE)

        image = None
        if style & wx.ICON_INFORMATION == wx.ICON_INFORMATION:
            image = os.path.join(itrade_config.dirRes, "box_info.png")
        if style & wx.ICON_ERROR == wx.ICON_ERROR:
            image = os.path.join(itrade_config.dirRes, "box_alert.png")
        if style & wx.ICON_QUESTION == wx.ICON_QUESTION:
            image = os.path.join(itrade_config.dirRes, "box_yesno.png")

        # container
        container = self.GetContentsPane()
        container.SetSizerType("vertical")

        # First Row : image + text
        pane = sc.SizedPanel(container, -1)
        pane.SetSizerType("horizontal")
        pane.SetSizerProps(expand=True)

        if image:
            image = wx.Bitmap(image)
            if image:
                bmp = wx.StaticBitmap(pane, -1, image)
                bmp.SetSizerProps(valign='center')

        if len(text)>96:
            h = 48
        else:
            h = 32
        txt = wx.StaticText(pane, -1, text, size=(260,h))
        txt.SetFont(wx.Font(10, wx.SWISS , wx.NORMAL, wx.NORMAL))

        txt.SetSizerProps(expand=True,valign='center',halign='center')

        # Last Row : OK, ..., Cancel
        btnpane = sc.SizedPanel(container, -1)
        btnpane.SetSizerType("horizontal")
        btnpane.SetSizerProps(halign='center')

        # context help
        if style & wx.HELP == wx.HELP:
            if wx.Platform != "__WXMSW__":
                btn = wx.ContextHelpButton(btnpane)

        # OK
        if style & wx.OK == wx.OK:
            btn = wx.Button(btnpane, wx.ID_OK, message('ok'))
            btn.SetDefault()
            btn.SetHelpText(message('ok_desc'))
            wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK)

        # YES
        if style & wx.YES == wx.YES:
            btn = wx.Button(btnpane, wx.ID_YES, message('yes'))
            if style & wx.YES_DEFAULT == wx.YES_DEFAULT: btn.SetDefault()
            #btn.SetHelpText(message('yes_desc'))
            wx.EVT_BUTTON(self, wx.ID_YES, self.OnYES)

        # NO
        if style & wx.NO == wx.NO:
            btn = wx.Button(btnpane, wx.ID_NO, message('no'))
            if style & wx.NO_DEFAULT == wx.NO_DEFAULT: btn.SetDefault()
            #btn.SetHelpText(message('no_desc'))
            wx.EVT_BUTTON(self, wx.ID_NO, self.OnNO)

        # CANCEL
        if style & wx.CANCEL == wx.CANCEL:
            btn = wx.Button(btnpane, wx.ID_CANCEL, message('cancel'))
            btn.SetHelpText(message('cancel_desc'))
            wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel)

        # a little trick to make sure that you can't resize the dialog to
        # less screen space than the controls need
        self.Fit()
        self.SetMinSize(self.GetSize())

    def OnOK(self,evt):
        self.EndModal(wx.ID_OK)

    def OnYES(self,evt):
        self.EndModal(wx.ID_YES)

    def OnNO(self,evt):
        self.EndModal(wx.ID_NO)

    def OnCancel(self,evt):
        self.EndModal(wx.ID_CANCEL)

# ============================================================================
# iTradeInformation()
#
#   parent          Parent window
#   text            Message to show on the dialog
#   caption         The dialog caption
# use : wxOK + wxICON_INFORMATION
# ============================================================================

def iTradeInformation(parent,text,caption=message('info_caption')):
    #dlg = HTMLDialog(parent=parent,caption=caption,text=text,buttons=OKButton(makedefault=1),image="box_info.png")
    dlg = iTradeDialog(parent=parent,caption=caption,text=text,style=wx.OK|wx.ICON_INFORMATION)
    idRet = dlg.ShowModal()
    dlg.Destroy()
    return idRet

# ============================================================================
# iTradeError()
#
#   parent          Parent window
#   text            Message to show on the dialog
#   caption         The dialog caption
# use : wxOK + wxICON_ERROR
# ============================================================================

def iTradeError(parent,text,caption=message('alert_caption')):
    #dlg = HTMLDialog(parent=parent,caption=caption,text=text,buttons=OKButton(makedefault=1),image="box_alert.png")
    dlg = iTradeDialog(parent=parent,caption=caption,text=text,style=wx.OK|wx.ICON_ERROR)
    idRet = dlg.ShowModal()
    dlg.Destroy()
    return idRet

# ============================================================================
# iTradeYesNo()
#
#   parent          Parent window
#   text            Message to show on the dialog
#   caption         The dialog caption
#   bCanCancel      yes/no
#   bYesDefault     yes/no
# use : wxYES_NO + { wxCANCEL) + wxICON_QUESTION
# ============================================================================

def iTradeYesNo(parent,text,caption,bCanCancel=False,bYesDefault=True):
    #buttons = YesButton(makedefault=bYesDefault)+NoButton(makedefault=not bYesDefault)
    #if bCanCancel:
    #    buttons = buttons+CancelButton(makedefault=0)
    #dlg = HTMLDialog(parent=parent,caption=caption,text=text,buttons=buttons,image="box_yesno.png")

    style = wx.YES_NO | wx.ICON_QUESTION
    if bCanCancel:
        style = style | wx.CANCEL
    if bYesDefault:
        style = style | wx.YES_DEFAULT
    else:
        style = style | wx.NO_DEFAULT

    dlg = iTradeDialog(parent=parent,caption=caption,text=text,style=style)
    idRet = dlg.ShowModal()
    dlg.Destroy()
    return idRet

# ============================================================================
# Test me
# ============================================================================

if __name__=='__main__':
    setLevel(logging.INFO)

    app = wx.PySimpleApp()

    iRet = iTradeYesNo(None,"message without cancel and default to Yes","caption")
    if iRet == wx.ID_YES:
        iRet = iTradeYesNo(None,"message with cancel and default to No","caption",bCanCancel=True,bYesDefault=False)
        if iRet == wx.ID_YES:
            iTradeInformation(None,message('portfolio_exist_info')% "message with some accents in French ... ")
        elif iRet == wx.ID_NO:
            iTradeInformation(None,"unconfirmation message")
        else:
            iTradeInformation(None,"cancellation message .............................. very long ........................... message ........... at least three (3) lines !!!!!!!!!!!")
    else:
        iTradeError(None,"test aborted message")

# ============================================================================
# That's all folks !
# ============================================================================
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.