-
Notifications
You must be signed in to change notification settings - Fork 17
/
Help.py
187 lines (164 loc) · 8.86 KB
/
Help.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# Copyright (C) 2003 - 2015 The Board of Regents of the University of Wisconsin System
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# 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; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
"""This file handles the Transana Help System. """
__author__ = 'David Woods <[email protected]>'
DEBUG = False
if DEBUG:
print "Help.py DEBUG is ON!!"
# import wxPython
import wx
# import the wxPython html module
import wx.html
# import Python's os and sys modules
import os, sys
# import Python's pickle module
import pickle
class Help(object):
""" This class implements Help Calls to the Transana Manual """
# Show the Manual's Welcome page if no context is supplied
def __init__(self, HelpContext='Manual'):
self.help = wx.html.HtmlHelpController()
# This has emerged as the "preferred" method on the wxPython-users list.
programDir = os.path.abspath(sys.path[0])
# Okay, that doesn't work with wxversion, which adds to the path. Here's the fix, I hope.
# This should over-ride the programDir with the first value that contains Transana in the path.
for path in sys.path:
if 'transana' in path.lower():
programDir = path
break
if os.path.isfile(programDir):
programDir = os.path.dirname(programDir)
# If we've done a build on the Mac, we need to adjust the path!!
if hasattr(sys, "frozen") and ('wxMac' in wx.PlatformInfo):
# Split the path into it's element directories
pathElements = programDir.split(os.sep)
# Initialize the Program Directory
programDir = ''
# Iterate through the path elements, skipping the blank firt one and the last two, which get added in the
# build process
for element in pathElements[1:-2]:
# Add a path separator and the path element
programDir += os.sep + element
if DEBUG:
msg = "Help.__init__(): programDir = %s" % programDir
import Dialogs
tmpDlg = Dialogs.InfoDialog(None, msg)
tmpDlg.ShowModal()
tmpDlg.Destroy()
# There's a problem with wxPython 2.8.3.0 that causes the Help Window to close when a Search is performed.
# Robin Dunn, author of wxPython, writes:
#
# The frame isn't created right away, so you need to do it later.
#
# The problem I worked around is the fact that the frame used by the
# HtmlHelpController is set to not prevent the exit of MainLoop, so
# if some other top level window closes (such as the search dialog)
# then there is no other TLW left besides the help frame, so the App
# will exit MainLoop.
#
# So if you are using the HtmlHelpController in a situation where there
# are no other TLW's in the same app then you'll have the same problem.
# I worked around it in wx.tools.helpviewer by making a frame that is
# never shown and uses the help frame as it's parent so it will get
# destroyed when the help frame closes. You can also call
# wx.GetApp().SetExitOnFrameDelete(False) but then you'll have to worry
# about exiting MainLoop yourself.
# The following comments and line of code, plus the method it calls, are
# based on Robin's code for implementing this.
# The frame used by the HtmlHelpController is set to not prevent
# app exit, so in the case of a standalone helpviewer like this
# when the about box or search box is closed the help frame will
# be the only one left and the app will close unexpectedly. To
# work around this we'll create another frame that is never shown,
# but which will be closed when the helpviewer frame is closed.
wx.CallAfter(self.makeOtherFrame, self.help)
# Now we add the actual contents to the HelpCtrl
self.help.AddBook(os.path.join(programDir, 'help', 'Manual.hhp'))
self.help.AddBook(os.path.join(programDir, 'help', 'Tutorial.hhp'))
self.help.AddBook(os.path.join(programDir, 'help', 'TranscriptNotation.hhp'))
# And finally, we display the Help Control, showing the current contents.
self.help.Display(HelpContext)
def makeOtherFrame(self, helpctrl):
""" See long comment above, with the CallAfter line. This is code from Robin Dunn. """
# Get the control's Frame
parent = helpctrl.GetFrame()
# Create another frame with the HelpCtrl as the parent. This provides a Top Level
# Window that is never shown but still prevents the program from exiting when the
# Search Dialog is closed. Because it has the HelpCtrl as a parent, it will close
# automatically.
otherFrame = wx.Frame(parent)
# Now that we have access to the Frame (because this is in a CallAfter situation),
# we can change the size of the Help Window. Yea!
if parent != None:
# Load the Config Data. wxConfig automatically uses the Registry on Windows and the appropriate file on Mac.
# Program Name is Transana, Vendor Name is Verception to remain compatible with Transana 1.0.
config = wx.Config('Transana', 'Verception')
# Load the Primary Screen setting
primaryScreen = config.ReadInt('/2.0/PrimaryScreen', 0)
# Get the size of the screen
rect = wx.Display(primaryScreen).GetClientArea() # wx.ClientDisplayRect()
# Set the top to 10% of the screen height (rect[1] is for secondary monitors)
top = int(0.1 * rect[3]) + rect[1]
# Set the height so that the top and bottom will have equal boundaries
height = rect[3] - (2 * top)
# Set the window width to 80% of the screen or 1000 pixels, whichever is smaller
width = min(int(rect[2] * 0.8), 1000)
# Set the left margin so that the window is centered (rect[0] is for secondary monitors)
left = int(rect[2] / 2) - int(width / 2) + rect[0]
# Position the window based on the calculated position
parent.SetPosition(wx.Point(left, top))
# Size the window based on the calculated size
parent.SetSize(wx.Size(width, height))
# We need the Help Control to run stand-alone
if __name__ == '__main__':
# Import Python's sys module
import sys
class MyApp(wx.App):
""" Application class for the Transana Help application """
def OnInit(self):
# Initialize the Help context
helpContext = ''
# NOTE: The Mac lacks the capacity for command line parameters, so we pass the help context via
# a pickled string on the Mac and by command line elsewhere.
# If we're on a Mac ...
if "__WXMAC__" in wx.PlatformInfo:
# ... start by looking for the pickle file containing the help context we should look for.
if os.path.exists(os.getenv("HOME") + '/TransanaHelpContext.txt'):
# If the file exists, open it.
helpfile = open(os.getenv("HOME") + '/TransanaHelpContext.txt', 'r')
# use pickle to read the pickled contents of the file
helpContext = pickle.load(helpfile)
# Close the help file.
helpfile.close()
# Once we've read it, we can delete the file!
os.remove(os.getenv("HOME") + '/TransanaHelpContext.txt')
# If we're NOT on a Mac ...
else:
# ... iterate through the command line parameters. (Multiple word help contexts are passed as multiple parameters.)
for paramCount in range(1, len(sys.argv)):
# Build the help context from the parameters
helpContext = helpContext + sys.argv[paramCount] + ' '
# If no help context is provided ...
if helpContext == '':
# ... use the default Help Context
helpContext = 'Manual'
# Create the frame, passing the help context
self.frame = Help(helpContext.strip())
return True
# Define the Application Object
app = MyApp(0)
# Run the Application's Main Loop
app.MainLoop()