Help.py :  » IDE » Boa-Constructor » boa-constructor-0.6.1 » 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 » IDE » Boa Constructor 
Boa Constructor » boa constructor 0.6.1 » Help.py
#----------------------------------------------------------------------
# Name:        Help.py
# Purpose:
#
# Author:      Riaan Booysen
#
# Created:     1999, rewritten 2001
# RCS-ID:      $Id: Help.py,v 1.33 2007/07/02 15:01:04 riaan Exp $
# Copyright:   (c) 1999 - 2007 Riaan Booysen
# Licence:     GPL
#----------------------------------------------------------------------
#Boa:FramePanel:PyDocHelpPage

import os, sys, marshal, string, socket, webbrowser

import wx
import wx.html
from wx.lib.anchors import LayoutAnchors

import Preferences, Utils
from Utils import _

[wxID_PYDOCHELPPAGE, wxID_PYDOCHELPPAGEBOXRESULTS,
 wxID_PYDOCHELPPAGEBTNSEARCH, wxID_PYDOCHELPPAGEBTNSTOP,
 wxID_PYDOCHELPPAGECHKRUNSERVER, wxID_PYDOCHELPPAGEPNLSTATUS,
 wxID_PYDOCHELPPAGESTXSTATUS, wxID_PYDOCHELPPAGETXTSEARCH,
] = [wx.NewId() for _init_ctrls in range(8)]

class PyDocHelpPage(wx.Panel):
    def _init_utils(self):
        # generated method, don't edit
        self.scrBrowse =wx.StockCursor(id=wx.CURSOR_HAND)

    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Panel.__init__(self, id=wxID_PYDOCHELPPAGE, name='PyDocHelpPage',
              parent=prnt, pos=wx.Point(443, 285), size=wx.Size(259, 456),
              style=wx.TAB_TRAVERSAL)
        self._init_utils()
        self.SetClientSize(wx.Size(251, 429))
        self.SetAutoLayout(True)

        self.txtSearch =wx.TextCtrl(id=wxID_PYDOCHELPPAGETXTSEARCH,
              name='txtSearch', parent=self, pos=wx.Point(10, 10),
              size=wx.Size(231, 21), style=0, value='')
        self.txtSearch.SetConstraints(LayoutAnchors(self.txtSearch, True, True,
              True, False))
        self.txtSearch.SetToolTipString(_('Enter name to search for'))
        self.txtSearch.Bind(wx.EVT_TEXT_ENTER, self.OnTxtsearchTextEnter, id=wxID_PYDOCHELPPAGETXTSEARCH)

        self.boxResults =wx.ListBox(choices=[], id=wxID_PYDOCHELPPAGEBOXRESULTS,
              name='boxResults', parent=self, pos=wx.Point(2, 89),
              size=wx.Size(247, 338), style=0)
        self.boxResults.SetConstraints(LayoutAnchors(self.boxResults, True,
              True, True, True))
        self.boxResults.Bind(wx.EVT_LISTBOX, self.OnBoxresultsListboxDclick, id=wxID_PYDOCHELPPAGEBOXRESULTS)

        self.btnSearch =wx.Button(id=wxID_PYDOCHELPPAGEBTNSEARCH,
              label=_('Search'), name='btnSearch', parent=self, pos=wx.Point(89,
              41), size=wx.Size(75, 23), style=0)
        self.btnSearch.SetConstraints(LayoutAnchors(self.btnSearch, False, True,
              True, False))
        self.btnSearch.Bind(wx.EVT_BUTTON, self.OnBtnsearchButton, id=wxID_PYDOCHELPPAGEBTNSEARCH)

        self.btnStop =wx.Button(id=wxID_PYDOCHELPPAGEBTNSTOP, label=_('Stop'),
              name='btnStop', parent=self, pos=wx.Point(166, 41), size=wx.Size(75,
              23), style=0)
        self.btnStop.SetConstraints(LayoutAnchors(self.btnStop, False, True,
              True, False))
        self.btnStop.Enable(False)
        self.btnStop.Bind(wx.EVT_BUTTON, self.OnBtnstopButton, id=wxID_PYDOCHELPPAGEBTNSTOP)

        self.chkRunServer =wx.CheckBox(id=wxID_PYDOCHELPPAGECHKRUNSERVER,
              label=_('Server'), name='chkRunServer', parent=self, pos=wx.Point(3,
              72), size=wx.Size(73, 13), style=0)
        self.chkRunServer.SetValue(self.runServer)
        self.chkRunServer.Bind(wx.EVT_CHECKBOX, self.OnChkrunserverCheckbox, id=wxID_PYDOCHELPPAGECHKRUNSERVER)

        self.pnlStatus =wx.Panel(id=wxID_PYDOCHELPPAGEPNLSTATUS,
              name='pnlStatus', parent=self, pos=wx.Point(80, 72),
              size=wx.Size(168, 16), style=wx.TAB_TRAVERSAL | wx.NO_BORDER)

        self.stxStatus =wx.StaticText(id=wxID_PYDOCHELPPAGESTXSTATUS,
              label=_('Server not running '), name='stxStatus',
              parent=self.pnlStatus, pos=wx.Point(0, 0), size=wx.Size(168, 16),
              style=wx.ST_NO_AUTORESIZE | wx.ALIGN_RIGHT)
        self.stxStatus.SetConstraints(LayoutAnchors(self.stxStatus, True, True,
              True, False))
        self.stxStatus.Bind(wx.EVT_LEFT_DOWN, self.OnStxstatusLeftDown)

    def __init__(self, parent, helpFrame):
        #print 'creating new PyDocPage'
        self.runServer = False
        self.runServer = helpFrame.pdRunServer

        self._init_ctrls(parent)

        self.helpFrame = helpFrame

        self.scanner = None
        self.server = self.helpFrame.controller.server = None
        self.url = ''

        self.statusHyperlinked = 0
        self.waiting = 0

        if self.runServer:
            self.chkRunServer.Disable()
            self.startPydocServer()

    def startPydocServer(self):
        # silence warnings
        import warnings
        warnings.filterwarnings('ignore', '', DeprecationWarning, 'pydoc')

        self.stxStatus.SetLabel(_('Starting pydoc server... '))

        if not testPydocServerAddress('localhost', 7464):
            self.stxStatus.SetLabel(_('Address in use, '))

            self.chkRunServer.Enable(True)
            self.chkRunServer.SetValue(False)
            self.runServer = False

            self.url = 'http://localhost:%d/'%7464
        else:
            self.waiting = 1
            import threading, pydoc
            threading.Thread(
                target=pydoc.serve, args=(7464, self.OnServerReady,
                    self.OnServerQuit)).start()

    # called from thread
    def OnServerReady(self, server):
        if self and self.helpFrame:
            self.server = self.helpFrame.controller.server = server
            self.url = server.url
            self.runServer = True
            self.waiting = 0

            wx.CallAfter(self.chkRunServer.Enable, True)
            wx.CallAfter(self.chkRunServer.SetValue, True)
            wx.CallAfter(self.hyperlinkLabel,
                              'http://localhost:%d/'%server.server_port)


    # called from thread
    def OnServerQuit(self):
        if self and self.stxStatus:
            self.server.server_close()
            self.server = None
            self.runServer = False
            self.url = ''
            self.waiting = 0

            wx.CallAfter(self.chkRunServer.Enable, True)
            wx.CallAfter(self.chkRunServer.SetValue, False)
            wx.CallAfter(self.stxStatus.SetLabel, _('Server quit. '))

    def OnBtnsearchButton(self, event):
        self.doSearch()

    def OnBtnstopButton(self, event):
        self.doStop()

    def doSearch(self):
        key = self.txtSearch.GetValue()
        self.btnStop.Enable(True)
        self.boxResults.Clear()

        import threading, pydoc
        if self.scanner:
            self.scanner.quit = 1
        self.scanner = pydoc.ModuleScanner()
        threading.Thread(target=self.scanner.run,
                         args=(self.OnUpdateResults, key,
                               self.OnFinishedResults)).start()

    # called from thread
    def OnUpdateResults(self, path, modname, desc):
        if self:
            if modname[-9:] == '.__init__':
                modname = modname[:-9] + ' (package)'
            wx.CallAfter(self.boxResults.Append,
                              modname + ' - ' + (desc or '(no description)'))

    def doStop(self):
        if self and self.scanner:
            self.scanner.quit = 1
            self.scanner = None

    # called from thread
    def OnFinishedResults(self):
        if self:
            self.scanner = None
            wx.CallAfter(self.btnStop.Disable)

    def OnBoxresultsListboxDclick(self, event):
        selection = self.boxResults.GetStringSelection()
        if selection and self.url:
            modname = selection.split()[0]
            self.helpFrame.html.LoadPage(self.url + modname + '.html')

    def OnTxtsearchTextEnter(self, event):
        self.doSearch()

    def OnChkrunserverCheckbox(self, event):
        self.chkRunServer.Disable()

        self.runServer = event.IsChecked()

        if self.runServer:
            self.startPydocServer()
        else:
            if self.server:
                self.restoreLabel(_('Stopping server...'))
                self.server.quit = 1
                self.server.server_close()

    def hyperlinkLabel(self, text):
        f = self.stxStatus.GetFont()
        f.SetUnderlined(1)
        self.stxStatus.SetFont(f)
        self.stxStatus.SetForegroundColour(wx.Colour(0x11,0x22,0x88))
        self.stxStatus.SetLabel(text)
        self.pnlStatus.SetCursor(self.scrBrowse)
        self.statusHyperlinked = 1

    def restoreLabel(self, text):
        f = self.stxStatus.GetFont()
        f.SetUnderlined(0)
        self.stxStatus.SetFont(f)
        self.stxStatus.SetForegroundColour(wx.BLACK)
        self.stxStatus.SetLabel(text)
        self.pnlStatus.SetCursor(wx.STANDARD_CURSOR)
        self.statusHyperlinked = 0

    def OnStxstatusLeftDown(self, event):
        if self.statusHyperlinked:
            webbrowser.open(self.stxStatus.GetLabel())


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


def tagEater(strg):
    res = ''
    inTag = 0
    for i in range(len(strg)-1, -1, -1):
        if strg[i] == '>':
            inTag = 1
            continue
        elif strg[i] == '<':
            inTag = 0
            continue
        if not inTag:
            res = strg[i] + res
    return res

def showMainHelp(bookname):
    getHelpController().Display(bookname).ExpandBook(bookname)

def showCtrlHelp(wxClass, method=''):
    getHelpController().Display(wxClass).ExpandCurrAsWxClass(method)

def showHelp(filename):
    getHelpController().Display(filename)

def showContextHelp(word):
# not useful atm
##    if word.startswith('EVT_'):
##        word = 'wx%sEvent' % ''.join([s.lower().capitalize() 
##                                      for s in word[4:].split('_')])
##    elif word in sys.builtin_module_names:
##        word = '%s (built-in module)'%word
##    else:
##        try:
##            libPath = os.path.dirname(os.__file__)
##        except AttributeError, error:
##            pass
##        else:
##            if os.path.isfile('%s/%s.py'%(libPath, word)):
##                word = '%s (standard module)'%word
    if string.strip(word):
        getHelpController().Display(word).IndexFind(word)
    else:
        getHelpController().DisplayContents()

def decorateWxPythonWithDocStrs(dbfile):
    namespace = Utils.getEntireWxNamespace()

    try:
        db = marshal.load(open(dbfile, 'rb'))
    except IOError:
        print 'wxPython Doc strings: %s failed to load'%dbfile
    else:
        for name, doc in db['classes'].items():
            try:
                wxClass = namespace[name]
                wxClass.__doc__ = doc

                wxClass = namespace[name+'Ptr']
                wxClass.__doc__ = doc
            except:
                pass

        for name, doc in db['methods'].items():
            try:
                cls, mth = string.split(name, '.')
                wxMeth = getattr(namespace[cls], mth)
                wxMeth.im_func.__doc__ = doc

                wxMeth = getattr(namespace[cls+'Ptr'], mth)
                wxMeth.im_func.__doc__ = doc
            except:
                pass

class wxHtmlHelpControllerEx(wx.html.HtmlHelpController):
    frameX = None
    def Display(self, text):
        wx.html.HtmlHelpController.Display(self, text)
        if not self.frameX:
            self.frameX = wxHelpFrameEx(self)
        #frameX.restore()
        frame = self.frameX.frame
        if not frame.IsShown():
            frame.Show(True)
        if frame.IsIconized():
            frame.Iconize(False)
        frame.Raise()
        return self.frameX

    def UseConfig(self, config):
        # Fix config file if stored as minimised
        if config.ReadInt('hcX') == -32000:
            map(config.DeleteEntry, ('hcX', 'hcY', 'hcW', 'hcH'))

        wx.html.HtmlHelpController.UseConfig(self, config)

        self.config = config

class _CloseEvtHandler(wx.EvtHandler):
    def __init__(self, frameEx, controller):
        wx.EvtHandler.__init__(self)
        frameEx.frame.Bind(wx.EVT_CLOSE, self.OnClose)
        self.frameEx = frameEx
        self.frame = frameEx.frame
        self.controller = controller

    def OnClose(self, event):
        if hasattr(self.frameEx, 'pydocPage') and self.frameEx.pydocPage:
            config = self.frameEx.controller.config
            config.WriteInt('pdRunServer', self.frameEx.pydocPage.runServer)
            config.Flush()

        # catching the close event when running standalone
        if __name__ == '__main__':
            if not canClosePydocServer():
                if pydocWarning():
                    return
            event.Skip()
            self.frame.PopEventHandler().Destroy()

        if self.controller:
            self.controller.frameX = None
        event.Skip()#self.frame.Hide()

wxID_COPYTOCLIP =wx.NewId()

# Note, this works nicely because of OOR
class wxHelpFrameEx:
    def __init__(self, helpctrlr):
        self.controller = helpctrlr
        self.frame = helpctrlr.GetFrame()
        #self.frame.frameEx = self

        wxID_QUITHELP, wxID_FOCUSHTML = wx.NewId(), wx.NewId()
        self.frame.Bind(wx.EVT_MENU, self.OnQuitHelp, id=wxID_QUITHELP)
        self.frame.Bind(wx.EVT_MENU, self.OnFocusHtml, id=wxID_FOCUSHTML)

        self.frame.PushEventHandler(_CloseEvtHandler(self, helpctrlr))

        # helpfrm.cpp defines no accelerators so this is ok
        self.frame.SetAcceleratorTable(
              wx.AcceleratorTable([(0, wx.WXK_ESCAPE, wxID_QUITHELP),
                                  (wx.ACCEL_CTRL, ord('H'), wxID_FOCUSHTML),]))

        try:
            _none, self.toolbar, self.splitter = self.frame.GetChildren()
        # 2.7
        except ValueError:
            _statusBar, _helpWindow = self.frame.GetChildren()
            self.toolbar, self.splitter = _helpWindow.GetChildren()

        self.html, nav = self.splitter.GetChildren()

        self.navPages = nav.GetChildren()[0]

        # Extend toolbar
        if self.toolbar.FindById(wxID_COPYTOCLIP) is None:
            self.toolbar.AddSeparator()
            self.copyToClipId = wxID_COPYTOCLIP
            self.toolbar.AddTool(id = self.copyToClipId, isToggle=0,
                bitmap=Preferences.IS.load('Images/Shared/CopyHelp.png'),
                pushedBitmap=wx.NullBitmap,
                shortHelpString=_('Copy contents as text to clipboard'),
                longHelpString='')
            self.frame.Bind(wx.EVT_TOOL, self.OnCopyPage, id=self.copyToClipId)
            self.toolbar.Realize()

#        else:
#            self.navPages = nav.GetChildren()[0]

        assert self.navPages.GetPageText(0) == _('Contents')
        self.contentsPanel = self.navPages.GetPage(0)

        self.contentsAddBookmark, self.contentsDelBookmark, \
              self.contentsChooseBookmark, self.contentsTree = \
              self.contentsPanel.GetChildren()

        assert self.navPages.GetPageText(1) == _('Index')
        self.indexPanel = self.navPages.GetPage(1)

        self.indexTextCtrl, btn1, btn2 = \
              self.indexPanel.GetChildren()[:3]

        # done this way to work on 2.3.2 and 2.3.3
        if btn1.GetLabel() == _('Show all'):
            self.indexShowAllBtn, self.indexFindBtn = btn1, btn2
        else:
            self.indexShowAllBtn, self.indexFindBtn = btn2, btn1

        if Preferences.usePydocHelp and self.navPages.GetPageCount() == 3:
            self.pdRunServer = self.controller.config.ReadInt('pdRunServer', False)

            self.pydocPage = PyDocHelpPage(self.navPages, self)
            self.navPages.AddPage(self.pydocPage, 'Pydoc')
        else:
            self.pydocPage = None

##    def restore(self):
##        Utils.FrameRestorerMixin.restore(self.frame)

    def IndexFind(self, text):
        self.controller.DisplayIndex()
        self.indexTextCtrl.SetValue(text)

        wx.PostEvent(self.indexFindBtn, wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED,
              self.indexFindBtn.GetId()))

    def ShowNavPanel(self, show = True):
        if show:
            self.splitter.SplitVertically(self.navPages, self.html)
        else:
            self.splitter.Unsplit(self.navPages)

    def ExpandBook(self, name):
        self.navPages.SetSelection(0)
        rn = self.contentsTree.GetRootItem()
        nd, ck = self.contentsTree.GetFirstChild(rn)
        while nd.IsOk():
            if self.contentsTree.GetItemText(nd) == name:
                self.contentsTree.Expand(nd)
                break
            nd, ck = self.contentsTree.GetNextChild(rn, ck)

    def ExpandCurrAsWxClass(self, anchor):
        self.navPages.SetSelection(0)
        self.contentsTree.Expand(self.contentsTree.GetSelection())
        page = self.html.GetOpenedPage()
        if anchor:
            self.controller.Display('%s#%s' % (page, string.lower(anchor)))

    def OnQuitHelp(self, event):
        self.frame.Close()

    def OnFocusHtml(self, event):
        self.html.SetFocus()

    def OnCopyPage(self, event):
        Utils.writeTextToClipboard(self.html.SelectionToText())
        #Utils.html2txt(open(self.html.GetOpenedPage()).read()))

wxHF_TOOLBAR                = 0x0001
wxHF_CONTENTS               = 0x0002
wxHF_INDEX                  = 0x0004
wxHF_SEARCH                 = 0x0008
wxHF_BOOKMARKS              = 0x0010
wxHF_OPEN_FILES             = 0x0020
wxHF_PRINT                  = 0x0040
wxHF_FLAT_TOOLBAR           = 0x0080
wxHF_MERGE_BOOKS            = 0x0100
wxHF_ICONS_BOOK             = 0x0200
wxHF_ICONS_BOOK_CHAPTER     = 0x0400
wxHF_ICONS_FOLDER           = 0x0000
wxHF_DEFAULT_STYLE          = (wxHF_TOOLBAR | wxHF_CONTENTS | wxHF_INDEX | \
                               wxHF_SEARCH | wxHF_BOOKMARKS | wxHF_PRINT)

_hc = None

def getHelpController():
    if not _hc:
        initHelp()
    return _hc

def getCacheDir():
    cacheDir = os.path.join(Preferences.rcPath, 'docs-cache')
    if not os.path.isdir(cacheDir):
        cacheDir = os.path.join(Preferences.pyPath, 'Docs', 'cache')
    return cacheDir

# needed for .htb files
wx.FileSystem.AddHandler(wx.ZipFSHandler())

use_standard_controller = False
def initHelp(calledAtStartup=False):
    jn = os.path.join
    docsDir = jn(Preferences.pyPath, 'Docs')

    global _hc
    if use_standard_controller:
        _hc = wx.html.HtmlHelpController(wxHF_ICONS_BOOK_CHAPTER | \
            wxHF_DEFAULT_STYLE | (Preferences.flatTools and wxHF_FLAT_TOOLBAR or 0))
    else:
        _hc = wxHtmlHelpControllerEx(wxHF_ICONS_BOOK | \
            wxHF_DEFAULT_STYLE | (Preferences.flatTools and wxHF_FLAT_TOOLBAR or 0))
        cf = wx.FileConfig(localFilename=os.path.normpath(jn(Preferences.rcPath,
            'helpfrm.cfg')), style=wx.CONFIG_USE_LOCAL_FILE)
        _hc.UseConfig(cf)

    cacheDir = getCacheDir()
    _hc.SetTempDir(cacheDir)

    conf = Utils.createAndReadConfig('Explorer')
    books = eval(conf.get('help', 'books'), {})
    for book in books:
        if calledAtStartup:
            print 'Help: loading %s'% os.path.basename(book)
        bookPath = os.path.normpath(jn(docsDir, book))
        if os.path.exists(bookPath):
            _hc.AddBook(bookPath,
                  not os.path.exists(jn(cacheDir,
                  os.path.basename(book)+'.cached')) or not calledAtStartup)

def initWxPyDocStrs():
    docStrs = os.path.join(Preferences.pyPath, 'Docs', 'wxDocStrings.msh')
    decorateWxPythonWithDocStrs(docStrs)


def pydocWarning():
    return wx.MessageBox(_('The pydoc server has not completely started up yet,\n '
                        'it is safer to wait for it to finish before shutting '
                        'down.\n\nDo you want to wait?'), _('Pydoc server busy'),
                        wx.YES_NO | wx.ICON_EXCLAMATION) == wx.YES

def canClosePydocServer():
    if _hc:
        f = _hc.frameX
        if f and f.pydocPage and f.pydocPage.waiting:
            return False
    return True

def testPydocServerAddress(host, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        try:
            sock.bind((host, port))
        except socket.error, (code, msg):
            if code == 10048: # address in use
                return False
            raise
    finally:
        sock.close()
    return True

def delHelp():
    global _hc
    if _hc:
        try:
            _hc.config.Flush()
        except AttributeError:
            pass
        else:
            if hasattr(_hc, 'server') and _hc.server and not _hc.server.quit:
                _hc.server.quit = 1
                _hc.server.server_close()
    
            f = _hc.GetFrame()
            if f:
                #f.PopEventHandler().Destroy()
                f.Destroy()
        _hc.Destroy()
        _hc = None

def main(args):
    app = wx.PySimpleApp()
    initHelp()
    if args:
        showContextHelp(args[0])
    else:
        _hc.Display('')
    app.MainLoop()
    delHelp()

def _test(word):
    app = wx.PySimpleApp()
    initHelp()
    if word:
        showContextHelp(word)
    else:
        _hc.Display('')
    app.MainLoop()
    delHelp()


if __name__ == '__main__':
    #initWxPyDocStrs()
    main(sys.argv[1:])
    #_test('Window deletion overview')
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.