Beispiel #1
0
    def __init__(self, parent, id=-1):
        """Initialize an TranscriptToolbar object."""
        if 'wxGTK' in wx.PlatformInfo:
            size = wx.Size(560, 30)
        else:
            size = wx.Size(470, 30)
        # Create a ToolBar as self
        wx.ToolBar.__init__(self, parent, id, wx.DefaultPosition, size, wx.TB_HORIZONTAL | wx.BORDER_SIMPLE | wx.TB_FLAT | wx.TB_TEXT)
        # remember the parent
        self.parent = parent
        # Set the Toolbar Bitmap size
        self.SetToolBitmapSize((16, 16))
        # Keep a list of the tools placed on the toolbar so they're more easily manipulated
        self.tools = []

        # Create an Undo button
        self.CMD_UNDO_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_UNDO_ID, TransanaImages.Undo16.GetBitmap(),
                        shortHelpString=_('Undo action')))
        wx.EVT_MENU(self, self.CMD_UNDO_ID, self.OnUndo)

        self.AddSeparator()
  
        # Bold, Italic, Underline buttons
        self.CMD_BOLD_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_BOLD_ID, TransanaGlobal.GetImage(TransanaImages.Bold),
                        isToggle=1, shortHelpString=_('Bold text')))
        wx.EVT_MENU(self, self.CMD_BOLD_ID, self.OnBold)

        self.CMD_ITALIC_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_ITALIC_ID, TransanaGlobal.GetImage(TransanaImages.Italic),
                        isToggle=1, shortHelpString=_("Italic text")))
        wx.EVT_MENU(self, self.CMD_ITALIC_ID, self.OnItalic)
       
        self.CMD_UNDERLINE_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_UNDERLINE_ID, TransanaGlobal.GetImage(TransanaImages.Underline),
                        isToggle=1, shortHelpString=_("Underline text")))
        wx.EVT_MENU(self, self.CMD_UNDERLINE_ID, self.OnUnderline)

        self.AddSeparator()

        # Jeffersonian Symbols
        self.CMD_RISING_INT_ID = wx.NewId()
        bmp = wx.ArtProvider_GetBitmap(wx.ART_GO_UP, wx.ART_TOOLBAR, (16,16))
        self.tools.append(self.AddTool(self.CMD_RISING_INT_ID, bmp,
                        shortHelpString=_("Rising Intonation")))
        wx.EVT_MENU(self, self.CMD_RISING_INT_ID, self.OnInsertChar)
        
        self.CMD_FALLING_INT_ID = wx.NewId()
        bmp = wx.ArtProvider_GetBitmap(wx.ART_GO_DOWN, wx.ART_TOOLBAR, (16,16))
        self.tools.append(self.AddTool(self.CMD_FALLING_INT_ID, bmp,
                        shortHelpString=_("Falling Intonation")))
        wx.EVT_MENU(self, self.CMD_FALLING_INT_ID, self.OnInsertChar) 
       
        self.CMD_AUDIBLE_BREATH_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_AUDIBLE_BREATH_ID, TransanaGlobal.GetImage(TransanaImages.AudibleBreath),
                        shortHelpString=_("Audible Breath")))
        wx.EVT_MENU(self, self.CMD_AUDIBLE_BREATH_ID, self.OnInsertChar)
    
        self.CMD_WHISPERED_SPEECH_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_WHISPERED_SPEECH_ID, TransanaGlobal.GetImage(TransanaImages.WhisperedSpeech),
                        shortHelpString=_("Whispered Speech")))
        wx.EVT_MENU(self, self.CMD_WHISPERED_SPEECH_ID, self.OnInsertChar)
      
        self.AddSeparator()

        # Add show / hide timecodes button
        self.CMD_SHOWHIDE_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_SHOWHIDE_ID, TransanaGlobal.GetImage(TransanaImages.TimeCode16),
                        isToggle=1, shortHelpString=_("Show/Hide Time Code Indexes")))
        wx.EVT_MENU(self, self.CMD_SHOWHIDE_ID, self.OnShowHideCodes)

        # Add show / hide timecodes button
        self.CMD_SHOWHIDETIME_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_SHOWHIDETIME_ID, TransanaGlobal.GetImage(TransanaImages.TimeCodeData16),
                                       TransanaGlobal.GetImage(TransanaImages.TimeCodeData16),
                                       isToggle=1, shortHelpString=_("Show/Hide Time Code Values")))
        wx.EVT_MENU(self, self.CMD_SHOWHIDETIME_ID, self.OnShowHideValues)

        # Add read only / edit mode button
        self.CMD_READONLY_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_READONLY_ID, TransanaGlobal.GetImage(TransanaImages.ReadOnly16),
                                       TransanaGlobal.GetImage(TransanaImages.ReadOnly16),
                                       isToggle=1, shortHelpString=_("Edit/Read-only select")))
        wx.EVT_MENU(self, self.CMD_READONLY_ID, self.OnReadOnlySelect)

        # Add Formatring button
        self.CMD_FORMAT_ID = wx.NewId()
        # ... get the graphic for the Format button ...
        bmp = wx.ArtProvider_GetBitmap(wx.ART_HELP_SETTINGS, wx.ART_TOOLBAR, (16,16))
        # ... and create a Format button on the tool bar.
        self.tools.append(self.AddTool(self.CMD_FORMAT_ID, bmp, shortHelpString=_("Format")))
        wx.EVT_MENU(self, self.CMD_FORMAT_ID, self.OnFormat)

        self.AddSeparator()

        # Add QuickClip button
        self.CMD_QUICKCLIP_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_QUICKCLIP_ID, TransanaGlobal.GetImage(TransanaImages.QuickClip16),
                        shortHelpString=_("Create Quick Clip")))
        wx.EVT_MENU(self, self.CMD_QUICKCLIP_ID, self.OnQuickClip)

        # Add Edit keywords button
        self.CMD_KEYWORD_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_KEYWORD_ID, TransanaGlobal.GetImage(TransanaImages.KeywordRoot16),
                        shortHelpString=_("Edit Keywords")))
        wx.EVT_MENU(self, self.CMD_KEYWORD_ID, self.OnEditKeywords)

        # Add Save Button
        self.CMD_SAVE_ID = wx.NewId()
        self.tools.append(self.AddTool(self.CMD_SAVE_ID, TransanaGlobal.GetImage(TransanaImages.Save16),
                        shortHelpString=_("Save Transcript")))
        wx.EVT_MENU(self, self.CMD_SAVE_ID, self.OnSave)

        self.AddSeparator()

        # Add Propagate Changes Button
        # First, define the ID for this button
        self.CMD_PROPAGATE_ID = wx.NewId()
        # Now create the button and add it to the Tools list
        self.tools.append(self.AddTool(self.CMD_PROPAGATE_ID, TransanaGlobal.GetImage(TransanaImages.Propagate),
                        shortHelpString=_("Propagate Changes")))
        # Link the button to the appropriate event handler
        wx.EVT_MENU(self, self.CMD_PROPAGATE_ID, self.OnPropagate)

        self.AddSeparator()
        
        # Add Multi-Select Button
        # First, define the ID for this button
        self.CMD_MULTISELECT_ID = wx.NewId()
        # Now create the button and add it to the Tools list
        self.tools.append(self.AddTool(self.CMD_MULTISELECT_ID, TransanaGlobal.GetImage(TransanaImages.MultiSelect),
                        shortHelpString=_("Match Selection in Other Transcripts")))
        # Link the button to the appropriate event handler
        wx.EVT_MENU(self, self.CMD_MULTISELECT_ID, self.OnMultiSelect)

        # Add Multiple Transcript Play Button
        # First, define the ID for this button
        self.CMD_PLAY_ID = wx.NewId()
        # Now create the button and add it to the Tools list
        self.tools.append(self.AddTool(self.CMD_PLAY_ID, TransanaImages.Play.GetBitmap(),
                        shortHelpString=_("Play Multiple Transcript Selection")))
        # Link the button to the appropriate event handler
        wx.EVT_MENU(self, self.CMD_PLAY_ID, self.OnMultiPlay)

        self.AddSeparator()

        # SEARCH moved to TranscriptionUI because you can't put a TextCtrl on a Toolbar on the Mac!
        # Set the Initial State of the Editing Buttons to "False"
        for x in (self.CMD_UNDO_ID, self.CMD_BOLD_ID, self.CMD_ITALIC_ID, self.CMD_UNDERLINE_ID, \
                  self.CMD_RISING_INT_ID, self.CMD_FALLING_INT_ID, \
                  self.CMD_AUDIBLE_BREATH_ID, self.CMD_WHISPERED_SPEECH_ID, self.CMD_FORMAT_ID, \
                  self.CMD_PROPAGATE_ID, self.CMD_MULTISELECT_ID, self.CMD_PLAY_ID):
            self.EnableTool(x, False)

##        # On Windows, we need to display a "Transcript Health" indicator related to GDI resources.
##        # I tried to handle this through changing the "Save" button graphic in the Toolbar, but that
##        # caused the Search box to be disabled when the graphic was updated.  Weird.
##        if 'wxMSW' in wx.PlatformInfo:
##            # Create Bitmap objects for the four images used to populate the health indicator
##            self.GDIBmpAll = TransanaGlobal.GetImage(TransanaImages.StopLightAll)
##            self.GDIBmpRed = TransanaGlobal.GetImage(TransanaImages.StopLightRed)
##            self.GDIBmpYellow = TransanaGlobal.GetImage(TransanaImages.StopLightYellow)
##            self.GDIBmpGreen = TransanaGlobal.GetImage(TransanaImages.StopLightGreen)
##            # Create a Static Bitmap to display the Transcript Health indicator.  Start it with the neutral graphic
##            self.GDIBmp = wx.StaticBitmap(self, -1, self.GDIBmpAll)
##            self.AddControl(self.GDIBmp)
##            # Set the proper Tool Tip
##            self.GDIBmp.SetToolTip(wx.ToolTip(_("Transcript Healthy")))

        # Add Quick Search tools
        # Start with the Search Backwards button
        self.CMD_SEARCH_BACK_ID = wx.NewId()
        bmp = wx.ArtProvider_GetBitmap(wx.ART_GO_BACK, wx.ART_TOOLBAR, (16,16))
        self.tools.append(self.AddTool(self.CMD_SEARCH_BACK_ID, bmp,
                        shortHelpString=_("Search backwards")))
        wx.EVT_MENU(self, self.CMD_SEARCH_BACK_ID, self.parent.OnSearch)

        # Add the Search Text box
        self.searchText = wx.TextCtrl(self, -1, size=(100, 20), style=wx.TE_PROCESS_ENTER)
        self.AddControl(self.searchText)
        self.Bind(wx.EVT_TEXT_ENTER, self.parent.OnSearch, self.searchText)

        # Add the Search Forwards button
        self.CMD_SEARCH_NEXT_ID = wx.NewId()
        bmp = wx.ArtProvider_GetBitmap(wx.ART_GO_FORWARD, wx.ART_TOOLBAR, (16,16))
        self.tools.append(self.AddTool(self.CMD_SEARCH_NEXT_ID, bmp,
                        shortHelpString=_("Search forwards")))
        wx.EVT_MENU(self, self.CMD_SEARCH_NEXT_ID, self.parent.OnSearch)

        self.AddSeparator()

        # Add the Selection Label, which indicates the time position of the current selection
        self.selectionText = wx.StaticText(self, -1, "", size=wx.Size(200, 20))
        self.AddControl(self.selectionText)
    def __init__(self, parent):
        """ This is the Username, Password, Database Server, and Database Name Dialog """
        # For single-user Transana, all we need it the Database Name.  For multi-user Transana,
        # we need UserName, Password, Database Server, and Database Name.

        # First, let's set up some variables depending on whether we are in single-user or multi-user
        # mode.
        if TransanaConstants.singleUserVersion:
            # Dialog Title
            dlgTitle = _("Select Database")
            # Dialog Size
            dlgSize=(350, 40)
            # Instructions Text
            instructions = _("Please enter the name of the database you wish to use.\nTo create a new database, type in a new database name.\n(Database names may contain only letters and numbers in a single word.)")
            if TransanaConstants.demoVersion:
                instructions = _("Database selection has been disabled for the Demonstration Version.\n\nIn the full version of Transana, you can create as many separate\ndatabases as you want.\n")
            # Sizer Proportion for the instructions
            instProportion = 4
        else:
            # Dialog Title
            dlgTitle = _("Username and Password")
            # Dialog Size
            dlgSize=(450, 320)  # (350, 310)
            # Instructions Text
            instructions = _("Please enter your MySQL username and password, as well \nas the names of the server and database you wish to use.\nTo create a new database, type in a new database name\n(if you have appropriate permissions.)\n(Database names may contain only letters and numbers in\na single word.)")
            # Macs don't need as much space for instructions as Windows machines do.
            if 'wxMac' in wx.PlatformInfo:
                # Sizer Proportion for the instructions
                instProportion = 4
            else:
                # Sizer Proportion for the instructions
                instProportion = 6

        # Define the main Dialog Box
        wx.Dialog.__init__(self, parent, -1, dlgTitle, size=dlgSize, style=wx.CAPTION | wx.RESIZE_BORDER)

        # To look right, the Mac needs the Small Window Variant.
        if "__WXMAC__" in wx.PlatformInfo:
            self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        # Create a BoxSizer for the main elements to go onto the Panel
        userPanelSizer = wx.BoxSizer(wx.VERTICAL)

        # If we are in the Multi-user Version ...
        if not TransanaConstants.singleUserVersion:
            notebook = wx.Notebook(self, -1, size=self.GetSizeTuple())
            panelParent = notebook
            # Adding this line prevents an odd visual distortion in Arabic!
            notebook.SetBackgroundColour(wx.WHITE)
        else:
            panelParent = self

        # Place a Panel on the Dialog Box.  All Controls will go on the Panel.
        # (Panels can have DefaultItems, enabling the desired "ENTER" key functionality.
        userPanel = wx.Panel(panelParent, -1, name='UserNamePanel')

        # Instructions Text
        lblIntro = wx.StaticText(userPanel, -1, instructions)
        # Add the Instructions to the Main Sizer
#        userPanelSizer.Add(lblIntro, instProportion, wx.EXPAND | wx.ALL, 10)
        userPanelSizer.Add(lblIntro, 0, wx.ALL, 10) # instProportion, wx.EXPAND | wx.ALL, 10)

        # Get the dictionary of defined database hosts and databases from the Configuration module
        self.Databases = TransanaGlobal.configData.databaseList

        # With release 2.30, we add the Port parameter for MU.  This requires a change to the format of the
        # configuration data.  Therefore, we need to examine the structure of the configuration data.
        # If it exists and the data type is a list, we need to update the structure of the existing data.
        if (len(self.Databases) >0) and (type(self.Databases[self.Databases.keys()[0]]) == type([])):
            # Create a new Dictionary object
            newDatabases = {}
            # Iterate through the old dictionary object.  For each database server ...
            for dbServer in self.Databases.keys():
                # ... we need the database list AND the port.  Port 3306 was the only option until this change
                #, so makes an adequate default.
                newDatabases[dbServer] = {'dbList' : self.Databases[dbServer],
                                          'port' : '3306'}
            # Replace the old config data with this modified version.
            self.Databases = newDatabases

        # The multi-user version has more fields than the single-user version.
        # If not the single-user version, put these fields on the form.
        if not TransanaConstants.singleUserVersion:

            # Let's use a FlexGridSizer for the data entry fields.
            # for MU, we want 5 rows with 2 columns
#            box2 = wx.FlexGridSizer(5, 2, 6, 0)
            # We want to be flexible horizontally
#            box2.SetFlexibleDirection(wx.HORIZONTAL)
            # We want the data entry fields to expand
#            box2.AddGrowableCol(1)

            # The proportion for the data entry portion of the screen should be 6
#            box2Proportion = 0

            # Use a BoxSizer instead of a FlexGridSizer.  The FlexGridSizer isn't handling alternate font sizes
            # on Windows correctly.
#            box2 = wx.BoxSizer(wx.VERTICAL)

            # Create a Row Sizer for Username
            r1Sizer = wx.BoxSizer(wx.HORIZONTAL)
            # Username Label        
            lblUsername = wx.StaticText(userPanel, -1, _("Username:"******"Password:"******"Host / Server:"))
            r3Sizer.Add(lblDBServer, 1, wx.ALL, 5)

            # If Databases has entries, use that to create the Choice List for the Database Servers list.
            if self.Databases.keys() != []:
               choicelist = self.Databases.keys()
               choicelist.sort()
            # If not, create a list with a blank entry
            else:
               choicelist = ['']

            # As of wxPython 2.9.5.0, Mac doesn't support wx.CB_SORT and gives an ugly message about it!
            if 'wxMac' in wx.PlatformInfo:
                style = wx.CB_DROPDOWN
            else:
                style = wx.CB_DROPDOWN | wx.CB_SORT
            # Host / Server Combo Box, with a list of servers from the Databases Object if appropriate
            self.chDBServer = wx.ComboBox(userPanel, -1, choices=choicelist, style = style)

            # Set the value to the default value provided by the Configuration Data
            self.chDBServer.SetValue(TransanaGlobal.configData.host)
            r3Sizer.Add(self.chDBServer, 4, wx.EXPAND | wx.ALL, 5)
#            box2.Add(r3Sizer, 0, wx.EXPAND)
            userPanelSizer.Add(r3Sizer, 0, wx.EXPAND)

            # Define the Selection, SetFocus and KillFocus events for the Host / Server Combo Box
            wx.EVT_COMBOBOX(self, self.chDBServer.GetId(), self.OnServerSelect)

            # NOTE:  These events don't work on the MAC!  There appears to be a wxPython bug.  See wxPython ticket # 9862
            wx.EVT_KILL_FOCUS(self.chDBServer, self.OnServerKillFocus)

            # Create a Row Sizer for Port
            r4Sizer = wx.BoxSizer(wx.HORIZONTAL)
            # Define the Port TextCtrl and its KillFocus event
            lblPort = wx.StaticText(userPanel, -1, _("Port:"))
            r4Sizer.Add(lblPort, 1, wx.ALL, 5)
            self.txtPort = wx.TextCtrl(userPanel, -1, TransanaGlobal.configData.dbport, style=wx.TE_LEFT)
            r4Sizer.Add(self.txtPort, 4, wx.EXPAND | wx.ALL, 5)
#            box2.Add(r4Sizer, 0, wx.EXPAND)
            userPanelSizer.Add(r4Sizer, 0, wx.EXPAND)

            # This wx.EVT_SET_FOCUS is a poor attempt to compensate for wxPython bug # 9862
            if 'wxMac' in wx.PlatformInfo:
                self.txtPort.Bind(wx.EVT_SET_FOCUS, self.OnServerKillFocus)
            self.txtPort.Bind(wx.EVT_KILL_FOCUS, self.OnPortKillFocus)

#            # Let's add the MU controls we've created to the Data Entry Sizer
#            box2.AddMany([(lblUsername, 1, wx.RIGHT, 10),
#                          (self.txtUsername, 2, wx.EXPAND),
#                          (lblPassword, 1, wx.RIGHT, 10),
#                          (self.txtPassword, 2, wx.EXPAND),
#                          (lblDBServer, 1, wx.RIGHT, 10),
#                          (self.chDBServer, 2, wx.EXPAND),
#                          (lblPort, 1, wx.RIGHT, 10),
#                          (self.txtPort, 2, wx.EXPAND)
#                         ])
#        else:
#            # For single-user Transana, we only need one row with two columns
#            box2 = wx.FlexGridSizer(1, 2, 0, 0)
#            # We want the grid to grow horizontally
#            box2.SetFlexibleDirection(wx.HORIZONTAL)
#            # We want the data entry field to grow
#            box2.AddGrowableCol(1)
#            # Since there's only one row, the sizer proportion can be small.
#            box2Proportion = 2

            # The proportion for the data entry portion of the screen should be 6
#            box2Proportion = 0

            # Use a BoxSizer instead of a FlexGridSizer.  The FlexGridSizer isn't handling alternate font sizes
            # on Windows correctly.
#            box2 = wx.BoxSizer(wx.VERTICAL)

        # The rest of the controls are needed for both single- and multi-user versions.
        # Create a Row Sizer for Port
        r5Sizer = wx.BoxSizer(wx.HORIZONTAL)
        # Databases Label
        lblDBName = wx.StaticText(userPanel, -1, _("Database:"))
        r5Sizer.Add(lblDBName, 1, wx.ALL, 5)

        # If a Host is defined, get the list of Databases defined for that host.
        # The single-user version ...
        if TransanaConstants.singleUserVersion:
            # ... uses "localhost" as the server.
            DBServerName = 'localhost'
        # The multi-user version ...
        else:
            # ... uses whatever is selected in the DBServer Choice Box.
            DBServerName = self.chDBServer.GetValue()

        # There's a problem with wxPython's wxComboBox.  It sets the drop-down height to the number of options
        # in the initial choicelist, and keeps that even if the choicelist is changed.
        # To get around this, we give it a fake choice list with enough entries, then populate it later.
        choicelist = ['', '', '', '', '']

        # As of wxPython 2.9.5.0, Mac doesn't support wx.CB_SORT and gives an ugly message about it!
        if 'wxMac' in wx.PlatformInfo:
            style = wx.CB_DROPDOWN
        else:
            style = wx.CB_DROPDOWN | wx.CB_SORT
        # Database Combo Box
        self.chDBName = wx.ComboBox(userPanel, -1, choices=choicelist, style = style)

        # If we're in the Demo version ...
        if TransanaConstants.demoVersion:
            # ... then "Demonstration" is the only allowable Database Name
            self.chDBName.Clear()
            self.chDBName.Append("Demonstration")
            self.chDBName.SetValue("Demonstration")
            self.chDBName.Enable(False)
        # If we're NOT in the Demo version ...
        else:
            # If some Database have been defined...
            if len(self.Databases) >= 1:
                # ... Use the Databases object to get the list of Databases for the
                # identified Server
                if DBServerName != '':
                    choicelist = self.Databases[DBServerName]['dbList']
                    # Sort the Database List
                    choicelist.sort()
                else:
                    choicelist = ['']

                # Clear out the control's Choices ...
                self.chDBName.Clear()
                # ... and populate them with the appropriate values
                for choice in choicelist:
                    if ('unicode' in wx.PlatformInfo) and (isinstance(choice, str)):
                        choice = unicode(choice, 'utf8')  # TransanaGlobal.encoding)
                    self.chDBName.Append(choice)

            # if the configured database isn't in the database list, don't show it!
            # This can happen if you have a Russian database name but change away from Russian encoding
            # by changing languages during the session.

##            print
##            print "UsernameandPasswordClass.__init__():"
##            print TransanaGlobal.configData.database.encode('utf8'), type(TransanaGlobal.configData.database)
##            for x in range(len(choicelist)):
##                print choicelist[x], type(choicelist[x]), TransanaGlobal.configData.database.encode('utf8') == choicelist[x]
##            print TransanaGlobal.configData.database.encode('utf8') in choicelist, choicelist.index(TransanaGlobal.configData.database.encode('utf8'))
##            print
##
##            # If we're on the Mac ...
##            if 'wxMac' in wx.PlatformInfo:
##                # ... SetStringSelection is broken, so we locate the string's item number and use SetSelection!
##                if TransanaGlobal.configData.database in choicelist:
##                    self.chDBName.SetSelection(choicelist.index(TransanaGlobal.configData.database.encode('utf8')))  # (self.chDBName.GetItems().index(TransanaGlobal.configData.database.encode('utf8')))
##            else:
            if self.chDBName.FindString(TransanaGlobal.configData.database) != wx.NOT_FOUND:
                # Set the value to the default value provided by the Configuration Data
                self.chDBName.SetStringSelection(TransanaGlobal.configData.database)

        r5Sizer.Add(self.chDBName, 4, wx.EXPAND | wx.ALL, 5)
#        box2.Add(r5Sizer, 0, wx.EXPAND)
        userPanelSizer.Add(r5Sizer, 0, wx.EXPAND)

        # Define the SetFocus and KillFocus events for the Database Combo Box
        wx.EVT_KILL_FOCUS(self.chDBName, self.OnNameKillFocus)

        # Weird Mac bug ... Can't select all Database Names from the list sometimes.  So, if Mac ...
        if 'wxMac' in wx.PlatformInfo:
            # ... add a Combo Box Event handler for the Database Name selection
            self.chDBName.Bind(wx.EVT_COMBOBOX, self.OnNameSelect)

#        # Add the Database name fields to the Data Entry sizer
#        box2.AddMany([(lblDBName, 1, wx.RIGHT, 10),
#                      (self.chDBName, 2, wx.EXPAND)
#                     ])
        # Now add the Data Entry sizer to the Main sizer
#        userPanelSizer.Add(box2, box2Proportion, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
#        userPanelSizer.Add(box2, 0, wx.LEFT | wx.RIGHT, 10)

        # If we are in the Multi-user Version ...
        if not TransanaConstants.singleUserVersion:

            # Add an SSL checkbox to the Username panel
            self.sslCheck = wx.CheckBox(userPanel, -1, _("Use SSL") + "  ", style=wx.CHK_2STATE | wx.ALIGN_RIGHT )
            # If SSL is True in the configuration file ...
            if TransanaGlobal.configData.ssl:
                # ... check the box
                self.sslCheck.SetValue(True)
            # Add a Spacer
            userPanelSizer.Add((0, 5))
            # Add the checkbox to the Username panel
            userPanelSizer.Add(self.sslCheck, 0, wx.LEFT | wx.ALIGN_LEFT, 5)
            # Add a Spacer
            userPanelSizer.Add((0, 10))

            # Add the User Panel to the first Notebook tab
            notebook.AddPage(userPanel, _("Database"), True)

            # Import the Transana OptionsSettings module, needed for the Message Server panel
            import OptionsSettings

            # Create teh Message Server Panel (which parents the MessageServer and MessageServerPort TextCtrls)
            self.messageServerPanel = OptionsSettings.MessageServerPanel(notebook, name='Username.MessageServerPanel')
            # Add the Message Server Panel to the second Notebook 
            notebook.AddPage(self.messageServerPanel, _("Message Server"), False)

            # Create a Panel for the SSL information
            sslPanel = wx.Panel(notebook, -1, size=notebook.GetSizeTuple(), name='UsernameandPasswordClass.sslPanel')
            # Create a Sizer for the SSL Panel
            sslSizer = wx.BoxSizer(wx.VERTICAL)

            # Get wxPython's Standard Paths
            sp = wx.StandardPaths.Get()
            # Set the initial SSL Directory to the user's Document Directory
            self.sslDir = sp.GetDocumentsDir()

            # Add the Client Certificate File to the SSL Tab
            lblClientCert = wx.StaticText(sslPanel, -1, _("Database Server SSL Client Certificate File"), style=wx.ST_NO_AUTORESIZE)
            # Add the label to the Panel Sizer
            sslSizer.Add(lblClientCert, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
            
            # Add a spacer
            sslSizer.Add((0, 3))
            
            # Add the Client Certificate File TextCtrl to the SSL Tab
            self.sslClientCert = wx.TextCtrl(sslPanel, -1, TransanaGlobal.configData.sslClientCert)
            # Add the element to the Panel Sizer
            sslSizer.Add(self.sslClientCert, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)

            # Add a Browse button for the Client Certificate File
            self.sslClientCertBrowse = wx.Button(sslPanel, -1, _("Browse"))
            # Add the button to the Sizer
            sslSizer.Add(self.sslClientCertBrowse, 0, wx.LEFT | wx.BOTTOM, 10)
            # Bind the button to the event processor
            self.sslClientCertBrowse.Bind(wx.EVT_BUTTON, self.OnSSLButton)
            # Add a spacer
            sslSizer.Add((0, 5))

            # Add the Client Key File to the SSL Tab
            lblClientKey = wx.StaticText(sslPanel, -1, _("Database Server SSL Client Key File"), style=wx.ST_NO_AUTORESIZE)
            # Add the label to the Panel Sizer
            sslSizer.Add(lblClientKey, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
            # Add a spacer
            sslSizer.Add((0, 3))
            
            # Add the Client Key File TextCtrl to the SSL Tab
            self.sslClientKey = wx.TextCtrl(sslPanel, -1, TransanaGlobal.configData.sslClientKey)
            # Add the element to the Panel Sizer
            sslSizer.Add(self.sslClientKey, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)

            # Add a Browse button for the Client Key File
            self.sslClientKeyBrowse = wx.Button(sslPanel, -1, _("Browse"))
            # Add the button to the Sizer
            sslSizer.Add(self.sslClientKeyBrowse, 0, wx.LEFT | wx.BOTTOM, 10)
            # Bind the button to the event processor
            self.sslClientKeyBrowse.Bind(wx.EVT_BUTTON, self.OnSSLButton)

            # Add the Message Server Certificate File to the SSL Tab
            lblMsgSrvCert = wx.StaticText(sslPanel, -1, _("Message Server SSL Certificate File"), style=wx.ST_NO_AUTORESIZE)
            # Add the label to the Panel Sizer
            sslSizer.Add(lblMsgSrvCert, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
            # Add a spacer
            sslSizer.Add((0, 3))
            
            # Add the Message Server Certificate File TextCtrl to the SSL Tab
            self.sslMsgSrvCert = wx.TextCtrl(sslPanel, -1, TransanaGlobal.configData.sslMsgSrvCert)
            # Add the element to the Panel Sizer
            sslSizer.Add(self.sslMsgSrvCert, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)

            # Add a Browse button for the Message Server Certificate File
            self.sslMsgSrvCertBrowse = wx.Button(sslPanel, -1, _("Browse"))
            # Add the button to the Sizer
            sslSizer.Add(self.sslMsgSrvCertBrowse, 0, wx.LEFT | wx.BOTTOM, 10)
            # Bind the button to the event processor
            self.sslMsgSrvCertBrowse.Bind(wx.EVT_BUTTON, self.OnSSLButton)

            # Set the SSL Panel's Sizer
            sslPanel.SetSizer(sslSizer)
            # Turn on AutoLayout
            sslPanel.SetAutoLayout(True)
            # Lay out the panel
            sslPanel.Layout()

            # Add the SSL Panel as the third Notebook tab
            notebook.AddPage(sslPanel, _("SSL"), False)

        # Create another sizer for the buttons, with a horizontal orientation
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)

        # If this is NOT the Demo version ...
        if not TransanaConstants.demoVersion:
            # Define the "Delete Database" Button
            btnDeleteDatabase = wx.Button(self, -1, _("Delete Database"))
            self.Bind(wx.EVT_BUTTON, self.OnDeleteDatabase, btnDeleteDatabase)
            # Define the "Refresh Database List" button
            bmp = TransanaGlobal.GetImage(TransanaImages.Refresh)
            btnRefresh = wx.BitmapButton(self, -1, bmp)
            btnRefresh.SetToolTip(wx.ToolTip(_('Refresh Database List')))
            self.Bind(wx.EVT_BUTTON, self.OnRefresh, btnRefresh)

        # Define the "OK" button
        btnOK = wx.Button(self, wx.ID_OK, _("OK"))
        # Make the OK button the default.  (This one works on Linux, while the next line doesn't!)
        btnOK.SetDefault()
        # Define the Default Button for the dialog.  This allows the "ENTER" key
        # to fire the OK button regardless of which widget has focus on the form.
        self.SetDefaultItem(btnOK)
        
        # Define the Cancel Button
        btnCancel = wx.Button(self, wx.ID_CANCEL, _("Cancel"))

        # Define the "OK" button
        if not TransanaConstants.demoVersion:
            # Add the Delete Database button to the lower left corner
            buttonSizer.Add(btnDeleteDatabase, 3, wx.ALIGN_LEFT | wx.ALIGN_BOTTOM | wx.LEFT | wx.BOTTOM, 10)
            buttonSizer.Add(btnRefresh, 1, wx.ALIGN_LEFT | wx.ALIGN_BOTTOM | wx.LEFT | wx.BOTTOM, 10)
        # Lets have some space between this button and  the others.
        buttonSizer.Add((30, 1), 1, wx.EXPAND)
        # Add the OK button to the lower right corner
        buttonSizer.Add(btnOK, 2, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM | wx.RIGHT | wx.BOTTOM, 10)
        # Add the Cancel button to the lower right corner, bumping the OK button to the left
        buttonSizer.Add(btnCancel, 2, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM | wx.RIGHT | wx.BOTTOM, 10)

        # Lay out the panel and the form, request AutoLayout for both.
        userPanel.Layout()
        userPanel.SetAutoLayout(True)

        # Set the main Panel's sizer to the main sizer and "fit" it.
        userPanel.SetSizer(userPanelSizer)
        userPanel.Fit()

        # Remember the size of the UserPanel at this point, to determine what DISPLAY TEXT size is selected in Windows
        userPanelSize = userPanel.GetSize()

        # Let's stick the panel on a sizer to fit in the Dialog
        panSizer = wx.BoxSizer(wx.VERTICAL)
        if TransanaConstants.singleUserVersion:
            panSizer.Add(userPanel, 1, wx.EXPAND)
        else:
            panSizer.Add(notebook, 1, wx.EXPAND)
        panSizer.Add((0, 3))
            
        # Add the Button sizer to the main sizer
        panSizer.Add(buttonSizer, 0, wx.EXPAND)

        self.SetSizer(panSizer)
        self.Layout()

        self.SetAutoLayout(True)
        self.Fit()

        # Lay out the dialog box, and tell it to resize automatically
        self.Layout()

        # If we are in the Multi-user Version ...
        if not TransanaConstants.singleUserVersion:
            # ... if we're using Small or Normal fonts ...
            if userPanelSize[1] < 350:
                # ... this size should work for the dialog
                self.SetSize((self.GetSize()[0], 410))
            # ... but if we're using Medium fonts ...
            else:
                # ... we need a larger dialog size
                self.SetSize((520, 500))

        # Set minimum window size
        dlgSize = self.GetSizeTuple()
        self.SetSizeHints(dlgSize[0], dlgSize[1])

        # Center the dialog on the screen
        self.CentreOnScreen()

        # The Mac version needs the focus to be set explicitly.
        # If we're running single-user Transana ...
        if TransanaConstants.singleUserVersion:
            # ... focus on the Database name, which is the only field
            self.chDBName.SetFocus()
        # If we're running multi-user Transana ...
        else:
            # ... and we don't know the username ...
            if self.txtUsername.GetValue() == '':
                # ... then focus on the username ...
                self.txtUsername.SetFocus()
            # ... but if we DO know the username ...
            else:
                # ... then let's focus on the password instead.
                self.txtPassword.SetFocus()

        # Show the Form modally, process if OK selected        
        if self.ShowModal() == wx.ID_OK:
          # Save the Values
          if TransanaConstants.singleUserVersion:
              self.Username = ''
              self.Password = ''
              self.DBServer = 'localhost'
              self.Port     = '3306'
              self.SSL      = False
              self.MessageServer = ''
              self.MessageServerPort = ''
              self.SSLClientCert = ''
              self.SSLClientKey = ''
              self.SSLMsgSrvCert = ''
          else:
              self.Username = self.txtUsername.GetValue()
              self.Password = self.txtPassword.GetValue()
              self.DBServer = self.chDBServer.GetValue()
              self.Port     = self.txtPort.GetValue()
              self.SSL      = self.sslCheck.IsChecked()
              self.MessageServer = self.messageServerPanel.messageServer.GetValue()
              self.MessageServerPort = self.messageServerPanel.messageServerPort.GetValue()
              self.SSLClientCert = self.sslClientCert.GetValue()
              self.SSLClientKey = self.sslClientKey.GetValue()
              self.SSLMsgSrvCert = self.sslMsgSrvCert.GetValue()
          self.DBName   = self.chDBName.GetValue()

          # the EVT_KILL_FOCUS for the Combo Boxes isn't getting called on the Mac.  Let's call it manually here
          if "__WXMAC__" in wx.PlatformInfo:
              self.OnNameKillFocus(None)

          # Since the list could have been changed here, pass it back to the Configuration module so the appropriate
          # data will be saved during program shutdown
          TransanaGlobal.configData.databaseList = self.Databases
        else:   
          self.Username = ''
          self.Password = ''
          self.DBServer = ''
          self.DBName   = ''
          self.Port     = ''
          self.SSL      = False
          self.MessageServer = ''
          self.MessageServerPort = ''
          self.SSLClientCert = ''
          self.SSLClientKey = ''
          self.SSLMsgSrvCert = ''
        return None