コード例 #1
0
ファイル: TranscriptionUI.py プロジェクト: pehkawn/Transana
    def __init__(self, parent, id=-1, includeClose=False):
        # If we're including an optional Close button ...
        if includeClose:
            # ... define a style that includes the Close Box.  (System_Menu is required for Close to show on Windows in wxPython.)
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS | wx.SYSTEM_MENU | wx.CLOSE_BOX
        # If we don't need the close box ...
        else:
            # ... then we don't need that defined in the style
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS
        # Create the Dialog with the appropriate style
        wx.Dialog.__init__(self,
                           parent,
                           id,
                           _("Transcript"),
                           self.__pos(),
                           self.__size(),
                           style=style)

        # Set "Window Variant" to small only for Mac to make fonts match better
        if "__WXMAC__" in wx.PlatformInfo:
            self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.ControlObject = None  # The ControlObject handles all inter-object communication, initialized to None
        self.transcriptWindowNumber = -1

        # add the widgets to the panel
        sizer = wx.BoxSizer(wx.VERTICAL)

        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.toolbar = TranscriptToolbar(self)
        hsizer.Add(self.toolbar, 0, wx.ALIGN_TOP, 10)

        # Add Quick Search tools
        self.CMD_SEARCH_BACK_ID = wx.NewId()
        self.searchBack = wx.BitmapButton(
            self,
            self.CMD_SEARCH_BACK_ID,
            TransanaImages.ArtProv_BACK.GetBitmap(),
            style=wx.NO_BORDER)
        hsizer.Add(self.searchBack, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_BACK_ID, self.OnSearch)
        hsizer.Add((10, 1), 0)
        self.searchBackToolTip = wx.ToolTip(_("Search backwards"))
        self.searchBack.SetToolTip(self.searchBackToolTip)

        self.searchText = wx.TextCtrl(self,
                                      -1,
                                      size=(100, 20),
                                      style=wx.TE_PROCESS_ENTER)
        hsizer.Add(self.searchText, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearch, self.searchText)
        hsizer.Add((10, 1), 0)

        self.CMD_SEARCH_NEXT_ID = wx.NewId()
        self.searchNext = wx.BitmapButton(
            self,
            self.CMD_SEARCH_NEXT_ID,
            TransanaImages.ArtProv_FORWARD.GetBitmap(),
            style=wx.NO_BORDER)
        hsizer.Add(self.searchNext, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_NEXT_ID, self.OnSearch)
        self.searchNextToolTip = wx.ToolTip(_("Search forwards"))
        self.searchNext.SetToolTip(self.searchNextToolTip)

        self.EnableSearch(False)

        if ALLOW_UNICODE_ENTRY:
            self.UnicodeEntry = wx.TextCtrl(self,
                                            -1,
                                            size=(40, 16),
                                            style=wx.TE_PROCESS_ENTER)
            self.UnicodeEntry.SetMaxLength(4)
            hsizer.Add((10, 1), 0, wx.ALIGN_CENTER | wx.GROW)
            hsizer.Add(self.UnicodeEntry, 0,
                       wx.ALIGN_RIGHT | wx.TOP | wx.RIGHT, 8)
            self.UnicodeEntry.Bind(wx.EVT_TEXT, self.OnUnicodeText)
            self.UnicodeEntry.Bind(wx.EVT_TEXT_ENTER, self.OnUnicodeEnter)

        # Add a text label that will indicate the start and end points of the current transcript selection
        self.selectionText = wx.StaticText(self, -1, "")
        hsizer.Add(self.selectionText, 1,
                   wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 20)

        sizer.Add(hsizer, 0, wx.ALIGN_TOP | wx.EXPAND, 10)

        self.toolbar.Realize()

        self.editor = TranscriptEditor(self,
                                       id,
                                       self.toolbar.OnStyleChange,
                                       updateSelectionText=True)
        sizer.Add(self.editor, 1, wx.EXPAND, 10)
        if "__WXMAC__" in wx.PlatformInfo:
            # This adds a space at the bottom of the frame on Mac, so that the scroll bar will get the down-scroll arrow.
            sizer.Add((0, 15))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        # Set the focus in the Editor
        self.editor.SetFocus()

        # Capture Size Changes
        wx.EVT_SIZE(self, self.OnSize)

        try:
            # Defind the Activate event (for setting the active window)
            self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
            # Define the Close event (for THIS Transcript Window)
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        except:
            import sys
            print "TranscriptionUI._TranscriptDialog.__init__():"
            print sys.exc_info()[0]
            print sys.exc_info()[1]
            print
コード例 #2
0
ファイル: TranscriptionUI.py プロジェクト: EmmaZh/Transana
    def __init__(self, parent, id=-1, includeClose=False):
        # If we're including an optional Close button ...
        if includeClose:
            # ... define a style that includes the Close Box.  (System_Menu is required for Close to show on Windows in wxPython.)
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS | wx.SYSTEM_MENU | wx.CLOSE_BOX
        # If we don't need the close box ...
        else:
            # ... then we don't need that defined in the style
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS
        # Create the Dialog with the appropriate style
        wx.Dialog.__init__(self, parent, id, _("Transcript"), self.__pos(), self.__size(), style=style)

        # Set "Window Variant" to small only for Mac to make fonts match better
        if "__WXMAC__" in wx.PlatformInfo:
            self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.ControlObject = None            # The ControlObject handles all inter-object communication, initialized to None
        self.transcriptWindowNumber = -1

        # add the widgets to the panel
        sizer = wx.BoxSizer(wx.VERTICAL)

        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.toolbar = TranscriptToolbar(self)
        hsizer.Add(self.toolbar, 0, wx.ALIGN_TOP, 10)

        # Add Quick Search tools
        self.CMD_SEARCH_BACK_ID = wx.NewId()
        self.searchBack = wx.BitmapButton(self, self.CMD_SEARCH_BACK_ID, TransanaImages.ArtProv_BACK.GetBitmap(), style=wx.NO_BORDER)
        hsizer.Add(self.searchBack, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_BACK_ID, self.OnSearch)
        hsizer.Add((10, 1), 0)
        self.searchBackToolTip = wx.ToolTip(_("Search backwards"))
        self.searchBack.SetToolTip(self.searchBackToolTip)

        self.searchText = wx.TextCtrl(self, -1, size=(100, 20), style=wx.TE_PROCESS_ENTER)
        hsizer.Add(self.searchText, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearch, self.searchText)
        hsizer.Add((10, 1), 0)
        
        self.CMD_SEARCH_NEXT_ID = wx.NewId()
        self.searchNext = wx.BitmapButton(self, self.CMD_SEARCH_NEXT_ID, TransanaImages.ArtProv_FORWARD.GetBitmap(), style=wx.NO_BORDER)
        hsizer.Add(self.searchNext, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_NEXT_ID, self.OnSearch)
        self.searchNextToolTip = wx.ToolTip(_("Search forwards"))
        self.searchNext.SetToolTip(self.searchNextToolTip)

        self.EnableSearch(False)

        if ALLOW_UNICODE_ENTRY:
            self.UnicodeEntry = wx.TextCtrl(self, -1, size=(40, 16), style=wx.TE_PROCESS_ENTER)
            self.UnicodeEntry.SetMaxLength(4)
            hsizer.Add((10,1), 0, wx.ALIGN_CENTER | wx.GROW)
            hsizer.Add(self.UnicodeEntry, 0, wx.ALIGN_RIGHT | wx.TOP | wx.RIGHT, 8)
            self.UnicodeEntry.Bind(wx.EVT_TEXT, self.OnUnicodeText)
            self.UnicodeEntry.Bind(wx.EVT_TEXT_ENTER, self.OnUnicodeEnter)

        # Add a text label that will indicate the start and end points of the current transcript selection
        self.selectionText = wx.StaticText(self, -1, "")
        hsizer.Add(self.selectionText, 1, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 20)

        sizer.Add(hsizer, 0, wx.ALIGN_TOP | wx.EXPAND, 10)
            
        self.toolbar.Realize()
        
        self.editor = TranscriptEditor(self, id, self.toolbar.OnStyleChange, updateSelectionText=True)
        sizer.Add(self.editor, 1, wx.EXPAND, 10)
        if "__WXMAC__" in wx.PlatformInfo:
            # This adds a space at the bottom of the frame on Mac, so that the scroll bar will get the down-scroll arrow.
            sizer.Add((0, 15))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        # Set the focus in the Editor
        self.editor.SetFocus()

        # Capture Size Changes
        wx.EVT_SIZE(self, self.OnSize)

        try:
            # Defind the Activate event (for setting the active window)
            self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
            # Define the Close event (for THIS Transcript Window)
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        except:
            import sys
            print "TranscriptionUI._TranscriptDialog.__init__():"
            print sys.exc_info()[0]
            print sys.exc_info()[1]
            print
コード例 #3
0
ファイル: TranscriptionUI.py プロジェクト: pehkawn/Transana
class _TranscriptDialog(wx.Dialog):
    def __init__(self, parent, id=-1, includeClose=False):
        # If we're including an optional Close button ...
        if includeClose:
            # ... define a style that includes the Close Box.  (System_Menu is required for Close to show on Windows in wxPython.)
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS | wx.SYSTEM_MENU | wx.CLOSE_BOX
        # If we don't need the close box ...
        else:
            # ... then we don't need that defined in the style
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS
        # Create the Dialog with the appropriate style
        wx.Dialog.__init__(self,
                           parent,
                           id,
                           _("Transcript"),
                           self.__pos(),
                           self.__size(),
                           style=style)

        # Set "Window Variant" to small only for Mac to make fonts match better
        if "__WXMAC__" in wx.PlatformInfo:
            self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.ControlObject = None  # The ControlObject handles all inter-object communication, initialized to None
        self.transcriptWindowNumber = -1

        # add the widgets to the panel
        sizer = wx.BoxSizer(wx.VERTICAL)

        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.toolbar = TranscriptToolbar(self)
        hsizer.Add(self.toolbar, 0, wx.ALIGN_TOP, 10)

        # Add Quick Search tools
        self.CMD_SEARCH_BACK_ID = wx.NewId()
        self.searchBack = wx.BitmapButton(
            self,
            self.CMD_SEARCH_BACK_ID,
            TransanaImages.ArtProv_BACK.GetBitmap(),
            style=wx.NO_BORDER)
        hsizer.Add(self.searchBack, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_BACK_ID, self.OnSearch)
        hsizer.Add((10, 1), 0)
        self.searchBackToolTip = wx.ToolTip(_("Search backwards"))
        self.searchBack.SetToolTip(self.searchBackToolTip)

        self.searchText = wx.TextCtrl(self,
                                      -1,
                                      size=(100, 20),
                                      style=wx.TE_PROCESS_ENTER)
        hsizer.Add(self.searchText, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearch, self.searchText)
        hsizer.Add((10, 1), 0)

        self.CMD_SEARCH_NEXT_ID = wx.NewId()
        self.searchNext = wx.BitmapButton(
            self,
            self.CMD_SEARCH_NEXT_ID,
            TransanaImages.ArtProv_FORWARD.GetBitmap(),
            style=wx.NO_BORDER)
        hsizer.Add(self.searchNext, 0,
                   wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_NEXT_ID, self.OnSearch)
        self.searchNextToolTip = wx.ToolTip(_("Search forwards"))
        self.searchNext.SetToolTip(self.searchNextToolTip)

        self.EnableSearch(False)

        if ALLOW_UNICODE_ENTRY:
            self.UnicodeEntry = wx.TextCtrl(self,
                                            -1,
                                            size=(40, 16),
                                            style=wx.TE_PROCESS_ENTER)
            self.UnicodeEntry.SetMaxLength(4)
            hsizer.Add((10, 1), 0, wx.ALIGN_CENTER | wx.GROW)
            hsizer.Add(self.UnicodeEntry, 0,
                       wx.ALIGN_RIGHT | wx.TOP | wx.RIGHT, 8)
            self.UnicodeEntry.Bind(wx.EVT_TEXT, self.OnUnicodeText)
            self.UnicodeEntry.Bind(wx.EVT_TEXT_ENTER, self.OnUnicodeEnter)

        # Add a text label that will indicate the start and end points of the current transcript selection
        self.selectionText = wx.StaticText(self, -1, "")
        hsizer.Add(self.selectionText, 1,
                   wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 20)

        sizer.Add(hsizer, 0, wx.ALIGN_TOP | wx.EXPAND, 10)

        self.toolbar.Realize()

        self.editor = TranscriptEditor(self,
                                       id,
                                       self.toolbar.OnStyleChange,
                                       updateSelectionText=True)
        sizer.Add(self.editor, 1, wx.EXPAND, 10)
        if "__WXMAC__" in wx.PlatformInfo:
            # This adds a space at the bottom of the frame on Mac, so that the scroll bar will get the down-scroll arrow.
            sizer.Add((0, 15))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        # Set the focus in the Editor
        self.editor.SetFocus()

        # Capture Size Changes
        wx.EVT_SIZE(self, self.OnSize)

        try:
            # Defind the Activate event (for setting the active window)
            self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
            # Define the Close event (for THIS Transcript Window)
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        except:
            import sys
            print "TranscriptionUI._TranscriptDialog.__init__():"
            print sys.exc_info()[0]
            print sys.exc_info()[1]
            print

    def OnActivate(self, event):
        """ Activate Event for a Transcript Window """
        # If the Control Object is defined ...
        # There's a weird Mac bug.  If you click on the Visualization Window, then close one of the
        # multiple transcript windows, then right-click the Visualization, Transana crashes.
        # That's because, the act of closing the Transcript window calls that window's
        # TranscriptionUI.OnActivate() method AFTER its OnCloseWindow() method,
        # reseting self.ControlObject.activeTranscript to the window's transcriptWindowNumber, so the subsequent
        # Visualization call tried to activate a closed transcript window.  So here we will avoid that
        # by detecting that the number of Transcript Windows is smaller than this window's transcriptWindowNumber
        # and NOT resetting activeTranscript in that circumstance.
        if (self.ControlObject != None) and (self.transcriptWindowNumber < len(
                self.ControlObject.TranscriptWindow)):
            # ... make this transcript the Control Object's active trasncript
            self.ControlObject.activeTranscript = self.transcriptWindowNumber
        elif (self.ControlObject !=
              None) and (self.ControlObject.activeTranscript >= len(
                  self.ControlObject.TranscriptWindow)):
            self.ControlObject.activeTranscript = 0
        # Let the event fall through to parent windows.
        event.Skip()

    def OnCloseWindow(self, event):
        """ Event for the Transcript Window Close button, which should only exist on secondary transcript windows """
        if (self.transcriptWindowNumber > 0) or (len(
                self.ControlObject.TranscriptWindow) > 1):
            # Use the Control Object to close THIS transcript window
            self.ControlObject.CloseAdditionalTranscript(
                self.transcriptWindowNumber)
            # Allow the wxDialog's normal Close processing
            event.Skip()

    def OnSize(self, event):
        """ Transcription Window Resize Method """
        # If we are not doing global resizing of all windows ...
        if not TransanaGlobal.resizingAll:
            # Get the position of the Transcript window
            (left, top) = self.GetPositionTuple()
            # Get the size of the Transcript window
            (width, height) = self.GetSize()

            if DEBUG:
                print
                print 'Call 7', 'Transcript', width + left, top - 1

            # Call the ControlObject's routine for adjusting all windows
            self.ControlObject.UpdateWindowPositions('Transcript',
                                                     width + left,
                                                     YUpper=top - 1)
        # Call the Transcript Window's Layout.
        self.Layout()
        # We may need to scroll to keep the current selection in the visible part of the window.
        # Find the start of the selection.
        start = self.editor.GetSelectionStart()
        # Determine the visible line from the starting position's document line, and scroll so that the highlight
        # is 2 lines down, if possible.  (In wxSTC, the position in a document has a Document line, which does not
        # take line wrapping into account, and a visible line, which does.)
        self.editor.ScrollToLine(
            max(
                self.editor.VisibleFromDocLine(
                    self.editor.LineFromPosition(start) - 2), 0))

    def OnSearch(self, event):
        """ Implement the Toolbar's QuickSearch """
        # Get the text for the search
        txt = self.searchText.GetValue()
        # If there is text ...
        if txt != '':
            # Determine whether we're searching forward or backward
            if event.GetId() == self.CMD_SEARCH_BACK_ID:
                direction = "back"
            # Either CMD_SEARCH_FORWARD_ID or ENTER in the text box indicate forward!
            else:
                direction = "next"
            # Perform the search in the Editor
            self.editor.find_text(txt, direction)
            # Set the focus back on the editor component, rather than the button, so Paste or typing work.
            self.editor.SetFocus()

    def EnableSearch(self, enable):
        """ Change the "Enabled" status of the Search controls """
        self.searchBack.Enable(enable)
        self.searchText.Enable(enable)
        self.searchNext.Enable(enable)

    def ClearSearch(self):
        """ Clear the Search Box """
        self.searchText.SetValue('')

    def OnUnicodeText(self, event):
        s = event.GetString()
        if len(s) > 0:
            if not s[len(s) - 1].upper() in [
                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
                    'C', 'D', 'E', 'F'
            ]:
                self.UnicodeEntry.SetValue(s[:-1])
                self.UnicodeEntry.SetInsertionPoint(len(s) - 1)

    def OnUnicodeEnter(self, event):
        try:
            c = unichr(int(self.UnicodeEntry.GetValue(), 16))
            c = c.encode('utf8')  # (TransanaGlobal.encoding)
            curpos = self.editor.GetCurrentPos()
            len = self.editor.GetTextLength()
            self.editor.InsertText(curpos, c)
            len = self.editor.GetTextLength() - len
            self.editor.StartStyling(curpos, 0x7f)
            self.editor.SetStyling(len, self.editor.style)
            self.editor.GotoPos(curpos + len)
            self.UnicodeEntry.SetValue('')
            self.editor.SetFocus()
        except:
            pass

    def UpdateSelectionText(self, text):
        """ Update the text indicating the start and end points of the current selection """
        self.selectionText.SetLabel(text)

    def ChangeLanguages(self):
        """ Change Languages """
        self.searchBackToolTip.SetTip(_("Search backwards"))
        self.searchNextToolTip.SetTip(_("Search forwards"))

    def __size(self):
        """Determine the default size for the Transcript frame."""
        rect = wx.Display(TransanaGlobal.configData.primaryScreen
                          ).GetClientArea()  # wx.ClientDisplayRect()
        width = rect[2] * .715
        height = (rect[3] - TransanaGlobal.menuHeight) * .74
        return wx.Size(width, height)

    def __pos(self):
        """Determine default position of Transcript Frame."""
        rect = wx.Display(TransanaGlobal.configData.primaryScreen
                          ).GetClientArea()  # wx.ClientDisplayRect()
        (width, height) = self.__size()
        # rect[0] compensates if Start menu is on Left
        x = rect[0]
        # rect[1] compensates if Start menu is on Top
        y = rect[1] + rect[3] - height - 3
        return (x, y)
コード例 #4
0
ファイル: TranscriptionUI.py プロジェクト: EmmaZh/Transana
class _TranscriptDialog(wx.Dialog):

    def __init__(self, parent, id=-1, includeClose=False):
        # If we're including an optional Close button ...
        if includeClose:
            # ... define a style that includes the Close Box.  (System_Menu is required for Close to show on Windows in wxPython.)
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS | wx.SYSTEM_MENU | wx.CLOSE_BOX
        # If we don't need the close box ...
        else:
            # ... then we don't need that defined in the style
            style = wx.CAPTION | wx.RESIZE_BORDER | wx.WANTS_CHARS
        # Create the Dialog with the appropriate style
        wx.Dialog.__init__(self, parent, id, _("Transcript"), self.__pos(), self.__size(), style=style)

        # Set "Window Variant" to small only for Mac to make fonts match better
        if "__WXMAC__" in wx.PlatformInfo:
            self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.ControlObject = None            # The ControlObject handles all inter-object communication, initialized to None
        self.transcriptWindowNumber = -1

        # add the widgets to the panel
        sizer = wx.BoxSizer(wx.VERTICAL)

        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.toolbar = TranscriptToolbar(self)
        hsizer.Add(self.toolbar, 0, wx.ALIGN_TOP, 10)

        # Add Quick Search tools
        self.CMD_SEARCH_BACK_ID = wx.NewId()
        self.searchBack = wx.BitmapButton(self, self.CMD_SEARCH_BACK_ID, TransanaImages.ArtProv_BACK.GetBitmap(), style=wx.NO_BORDER)
        hsizer.Add(self.searchBack, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_BACK_ID, self.OnSearch)
        hsizer.Add((10, 1), 0)
        self.searchBackToolTip = wx.ToolTip(_("Search backwards"))
        self.searchBack.SetToolTip(self.searchBackToolTip)

        self.searchText = wx.TextCtrl(self, -1, size=(100, 20), style=wx.TE_PROCESS_ENTER)
        hsizer.Add(self.searchText, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearch, self.searchText)
        hsizer.Add((10, 1), 0)
        
        self.CMD_SEARCH_NEXT_ID = wx.NewId()
        self.searchNext = wx.BitmapButton(self, self.CMD_SEARCH_NEXT_ID, TransanaImages.ArtProv_FORWARD.GetBitmap(), style=wx.NO_BORDER)
        hsizer.Add(self.searchNext, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
        wx.EVT_BUTTON(self, self.CMD_SEARCH_NEXT_ID, self.OnSearch)
        self.searchNextToolTip = wx.ToolTip(_("Search forwards"))
        self.searchNext.SetToolTip(self.searchNextToolTip)

        self.EnableSearch(False)

        if ALLOW_UNICODE_ENTRY:
            self.UnicodeEntry = wx.TextCtrl(self, -1, size=(40, 16), style=wx.TE_PROCESS_ENTER)
            self.UnicodeEntry.SetMaxLength(4)
            hsizer.Add((10,1), 0, wx.ALIGN_CENTER | wx.GROW)
            hsizer.Add(self.UnicodeEntry, 0, wx.ALIGN_RIGHT | wx.TOP | wx.RIGHT, 8)
            self.UnicodeEntry.Bind(wx.EVT_TEXT, self.OnUnicodeText)
            self.UnicodeEntry.Bind(wx.EVT_TEXT_ENTER, self.OnUnicodeEnter)

        # Add a text label that will indicate the start and end points of the current transcript selection
        self.selectionText = wx.StaticText(self, -1, "")
        hsizer.Add(self.selectionText, 1, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 20)

        sizer.Add(hsizer, 0, wx.ALIGN_TOP | wx.EXPAND, 10)
            
        self.toolbar.Realize()
        
        self.editor = TranscriptEditor(self, id, self.toolbar.OnStyleChange, updateSelectionText=True)
        sizer.Add(self.editor, 1, wx.EXPAND, 10)
        if "__WXMAC__" in wx.PlatformInfo:
            # This adds a space at the bottom of the frame on Mac, so that the scroll bar will get the down-scroll arrow.
            sizer.Add((0, 15))
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        # Set the focus in the Editor
        self.editor.SetFocus()

        # Capture Size Changes
        wx.EVT_SIZE(self, self.OnSize)

        try:
            # Defind the Activate event (for setting the active window)
            self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
            # Define the Close event (for THIS Transcript Window)
            self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        except:
            import sys
            print "TranscriptionUI._TranscriptDialog.__init__():"
            print sys.exc_info()[0]
            print sys.exc_info()[1]
            print

    def OnActivate(self, event):
        """ Activate Event for a Transcript Window """
        # If the Control Object is defined ...
        # There's a weird Mac bug.  If you click on the Visualization Window, then close one of the
        # multiple transcript windows, then right-click the Visualization, Transana crashes.
        # That's because, the act of closing the Transcript window calls that window's
        # TranscriptionUI.OnActivate() method AFTER its OnCloseWindow() method,
        # reseting self.ControlObject.activeTranscript to the window's transcriptWindowNumber, so the subsequent
        # Visualization call tried to activate a closed transcript window.  So here we will avoid that
        # by detecting that the number of Transcript Windows is smaller than this window's transcriptWindowNumber
        # and NOT resetting activeTranscript in that circumstance.
        if (self.ControlObject != None) and (self.transcriptWindowNumber < len(self.ControlObject.TranscriptWindow)):
            # ... make this transcript the Control Object's active trasncript
            self.ControlObject.activeTranscript = self.transcriptWindowNumber
        elif (self.ControlObject != None) and (self.ControlObject.activeTranscript >= len(self.ControlObject.TranscriptWindow)):
            self.ControlObject.activeTranscript = 0
        # Let the event fall through to parent windows.
        event.Skip()

    def OnCloseWindow(self, event):
        """ Event for the Transcript Window Close button, which should only exist on secondary transcript windows """
        if (self.transcriptWindowNumber > 0) or (len(self.ControlObject.TranscriptWindow) > 1):
            # Use the Control Object to close THIS transcript window
            self.ControlObject.CloseAdditionalTranscript(self.transcriptWindowNumber)
            # Allow the wxDialog's normal Close processing
            event.Skip()

    def OnSize(self, event):
        """ Transcription Window Resize Method """
        # If we are not doing global resizing of all windows ...
        if not TransanaGlobal.resizingAll:
            # Get the position of the Transcript window
            (left, top) = self.GetPositionTuple()
            # Get the size of the Transcript window
            (width, height) = self.GetSize()

            if DEBUG:
                print
                print 'Call 7', 'Transcript', width + left, top - 1
            
            # Call the ControlObject's routine for adjusting all windows
            self.ControlObject.UpdateWindowPositions('Transcript', width + left, YUpper = top - 1)
        # Call the Transcript Window's Layout.
        self.Layout()
        # We may need to scroll to keep the current selection in the visible part of the window.
        # Find the start of the selection.
        start = self.editor.GetSelectionStart()
        # Determine the visible line from the starting position's document line, and scroll so that the highlight
        # is 2 lines down, if possible.  (In wxSTC, the position in a document has a Document line, which does not
        # take line wrapping into account, and a visible line, which does.)
        self.editor.ScrollToLine(max(self.editor.VisibleFromDocLine(self.editor.LineFromPosition(start) - 2), 0))

    def OnSearch(self, event):
        """ Implement the Toolbar's QuickSearch """
        # Get the text for the search
        txt = self.searchText.GetValue()
        # If there is text ...
        if txt != '':
            # Determine whether we're searching forward or backward
            if event.GetId() == self.CMD_SEARCH_BACK_ID:
                direction = "back"
            # Either CMD_SEARCH_FORWARD_ID or ENTER in the text box indicate forward!
            else:
                direction = "next"
            # Perform the search in the Editor
            self.editor.find_text(txt, direction)
            # Set the focus back on the editor component, rather than the button, so Paste or typing work.
            self.editor.SetFocus()

    def EnableSearch(self, enable):
        """ Change the "Enabled" status of the Search controls """
        self.searchBack.Enable(enable)
        self.searchText.Enable(enable)
        self.searchNext.Enable(enable)

    def ClearSearch(self):
        """ Clear the Search Box """
        self.searchText.SetValue('')
        
    def OnUnicodeText(self, event):
        s = event.GetString()
        if len(s) > 0:
            if not s[len(s)-1].upper() in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']:
                self.UnicodeEntry.SetValue(s[:-1])
                self.UnicodeEntry.SetInsertionPoint(len(s)-1)

    def OnUnicodeEnter(self, event):
        try:
            c = unichr(int(self.UnicodeEntry.GetValue(), 16))
            c = c.encode('utf8')  # (TransanaGlobal.encoding)
            curpos = self.editor.GetCurrentPos()
            len = self.editor.GetTextLength()
            self.editor.InsertText(curpos, c)
            len = self.editor.GetTextLength() - len
            self.editor.StartStyling(curpos, 0x7f)
            self.editor.SetStyling(len, self.editor.style)
            self.editor.GotoPos(curpos + len)
            self.UnicodeEntry.SetValue('')
            self.editor.SetFocus()
        except:
            pass

    def UpdateSelectionText(self, text):
        """ Update the text indicating the start and end points of the current selection """
        self.selectionText.SetLabel(text)

    def ChangeLanguages(self):
        """ Change Languages """
        self.searchBackToolTip.SetTip(_("Search backwards"))
        self.searchNextToolTip.SetTip(_("Search forwards"))

    def __size(self):
        """Determine the default size for the Transcript frame."""
        rect = wx.Display(TransanaGlobal.configData.primaryScreen).GetClientArea()  # wx.ClientDisplayRect()
        width = rect[2] * .715
        height = (rect[3] - TransanaGlobal.menuHeight) * .74
        return wx.Size(width, height)

    def __pos(self):
        """Determine default position of Transcript Frame."""
        rect = wx.Display(TransanaGlobal.configData.primaryScreen).GetClientArea()  # wx.ClientDisplayRect()
        (width, height) = self.__size()
        # rect[0] compensates if Start menu is on Left
        x = rect[0]
        # rect[1] compensates if Start menu is on Top
        y = rect[1] + rect[3] - height - 3
        return (x, y)